none
Silverlight 5 DataContractJsonSerializer Fails reading NetworkStream

    Question

  • Code that worked using Silverlight 4 no longer works in Silverlight 5. I get the Stream from the WebResponse.GetResponseStream(). I try passing that to the DataContractJsonSerializer, but it throws an exception saying it could not read a valid object type. However, if I insert a breakpoint right before serializer.ReadObject(stream), the code works!

    I did more hacking and was able to get the code to work sans breakpoints using the following:

    private const int _buffer_size = 1024 * 64;
    protected override Message ProcessResponseStream(Stream stream)
    {
        using (MemoryStream mem_stream = new MemoryStream())
        {
            byte[] buffer = new byte[_buffer_size];
            int amount_read = 0;
            while ((amount_read = stream.Read(buffer, 0, _buffer_size)) > 0)
                mem_stream.Write(buffer, 0, amount_read);
            mem_stream.Seek(0, SeekOrigin.Begin);
            return (Message)_serializer.ReadObject(mem_stream);
        }
    }

    The original code does not work (provided below) but used to work in Silverlight 4:

    protected override Message ProcessResponseStream(Stream stream)
    {
        return (Message)_serializer.ReadObject(stream);
    }

    As I said, if I provide a breakpoint at the ReadObject line, the function does not throw an exception. While debugging this issue, I also noticed that using a StreamReader on the NetworkStream and calling reader.ReadToEnd() returned NULL. However, if I iterated over the reader calling while ((line = reader.ReadLine()) != null) {} I actually got back text.

    Finally, when I created a StreamWriter that was supposed to insert lines from the NetworkStream into the MemoryStream, writer.Write(line) actually did not write anything to the memory stream! No exceptions were thrown, but the Length and Position properties did not change. I tried flushing to no avail. However, if I converted the line to bytes using the UTF8Encoding object, I could write those bytes directly to the MemoryStream.

    I know this doesn't make any sense. I had trouble believing it myself. I tried reading the DataContractJsonSerializer's decompiled code looking for clues (or somewhere that does a StreamReader.ReadToEnd()) but didn't see anything obvious. What is more troubling is that code that used to work in Silverlight 4 is broken in Silverlight 5. 

    Since I have a workaround, I am posting this as a warning and solution to a problem that other people may have. Also, I was hoping someone at Microsoft could offer some insight as to why I can't pass a NetworkStream directly to a DataContractJsonSerializer.

    Thanks.

    NB Surfer

    Monday, April 23, 2012 9:54 PM

All replies

  • Thanks to Josh G. for the solution.

    I was creating my WebRequest using HttpWebRequest.CreateHttp(URL). This was creating a Browser request.

    Instead, I should be creating a Client request using WebRequestCreator.ClientHttp.Create(new Uri(URL)). This solved the problem.

    Notice REST Requests require the Client request type: http://msdn.microsoft.com/en-us/library/cc838250(v=vs.95).

    Hope this helps.

    NB Surfer

    Wednesday, May 30, 2012 2:45 PM