Live SDK - Uploading XML file trough Memory Stream

I have a bit of a problem with the client.UploadAsync method of Live SDK (SkyDrive SDK). My code for some reason doesn't work or more specifically it uploads an empty file. It doesn't throw any error and the serialization to stream works (I know that for sure).

It even seems that the Memory Stream is OK. (since I have no tool to really see the data in it I just guess it is OK by looking at its 'Length' property).

The UploadAsync method is fine as well or at least it worked well when I first serialized the data into a .xml file in IsolatedStorage then read it with IsolatedStorageFileStream and then eventualy send that stream. (then it uploaded the data)

Any advice on why this may be happening?

  public void UploadFile<T>(string skyDriveFolderID, T data, string fileNameInSkyDrive)
    {
        this.fileNameInSkyDrive = fileNameInSkyDrive;
        {
            try
            {
                memoryStream =  new MemoryStream();

                XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
                xmlWriterSettings.Indent = true;

                XmlSerializer serializer = new XmlSerializer(typeof(T));
                using (XmlWriter xmlWriter = XmlWriter.Create(memoryStream, xmlWriterSettings))
                {
                    serializer.Serialize(xmlWriter, data);
                }
                client.UploadAsync(skyDriveFolderID, fileNameInSkyDrive, true, memoryStream, null);

            }

            catch (Exception ex)
            {
                if (memoryStream != null) { memoryStream.Dispose(); }
            }
        }
    }

Answers


You have to "rewind" the memorystream to the start before calling the UploadAsync method. Imagine the memorystream being like a tape which you record things on. The "read/write-head" is always floating over some point of the tape, which is the end in your case because you just wrote all serialized data onto it. The uploading method tries to read from it by moving forward on the tape, realizing it is already at its end. Thus you get an empty file uploaded.

The method you need for rewinding is:

memoryStream.Seek(0, SeekOrigin.Begin);

Also, it is good practice to use the using directive for IDisposable objects, which the memorystream is. This way you don't need a try {...} finally { ...Dispose(); } (this is done by the using).

Your method could then look like:

public void UploadFile<T>(string skyDriveFolderID, T data, string fileNameInSkyDrive)
{
    this.fileNameInSkyDrive = fileNameInSkyDrive;

    XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
    xmlWriterSettings.Indent = true;

    XmlSerializer serializer = new XmlSerializer(typeof(T));

    using (var memoryStream = new MemoryStream())
    {
        using (var xmlWriter = XmlWriter.Create(memoryStream, xmlWriterSettings))
        {
            serializer.Serialize(xmlWriter, data);
        }

        memoryStream.Seek(0, SeekOrigin.Begin);

        client.UploadAsync(skyDriveFolderID, fileNameInSkyDrive, true, memoryStream, null);
    }
}

Need Your Help

HTTP Post MQL4 to php

mql4 metatrader4

This is a piece of code I am trying to use to POST a set of 13 parameter values from the MQL4 script to an external php script, named upload.php

Curl FTP connection pooling

curl ftp

In my application I am executing curl.exe as external command to get list of files from an FTP folder. I need to scan multiple folders to the list so I am calling this command multiple times output...