question

HaabFred-4575 avatar image
0 Votes"
HaabFred-4575 asked PengDing-MSFT edited

Err Connection Reset Using WebInvoke JSON - Serialization problem.

I'm creating a simple web service that just returns data, but like most JSON data, there can be a hierarchy of different types. Here is a brief example of the code:


 using MyData = System.Collections.Generic.Dictionary<string, object>;
    
    [ServiceContract()]
     public interface IJSONReceiver
     {
         [OperationContract()]
         [WebInvoke(
             Method = "GET", UriTemplate = "TestData",
             ResponseFormat = WebMessageFormat.Json)]
         MyData TestData();
     }
    
     [ServiceBehaviorAttribute(InstanceContextMode = InstanceContextMode.Single)]
     public class JSONReceiver : IJSONReceiver
     {
         private Random rndm = new Random();
    
         MyData IJSONReceiver.TestData()
         {
             MyData rval = new MyData(); // MyDictionary();
             string[] shapes = { "Circle", "Square", "Triangle" };
             rval["line1"] = "Line One";
             rval["line2"] = "Line Two";
             rval["line3"] = "Line Three";
             rval["shape"] = shapes[rndm.Next(shapes.Length)];
             List<string> test = new List<string>();
             foreach(string s in shapes)
             {
                 test.Add(s);
             }
             rval["shapes"] = test; // HERE IS THE PROBLEM
             return rval;
         }
 }


As written above, when I try to access this from an external client (I'm using Postman for testing), or even from any browser, I get a Connection Reset error. I'm running this in debug mode in VS, there are no exceptions thrown, it just fails.

HOWEVER, if I comment out the problematic line (just before the return), it properly returns the JSON serialized data:

 [
     {
         "Key": "line1",
         "Value": "Line One"
     },
     {
         "Key": "line2",
         "Value": "Line Two"
     },
     {
         "Key": "line3",
         "Value": "Line Three"
     },
     {
         "Key": "shape",
         "Value": "Triangle"
     }
 ]

Now, I could force a different serializer - if I use the JavaScriptSerializer, the string it creates is correct, but then WebInvoke is doing another implicit serialization, which means the client would need to deserialize twice to the get the data correctly. That's very inelegant. If I could tell WebInvoke to NOT serialize (like WebMessageFormat.Bare, but it doesn't exist), it could also work.

Ultimately I feel like I need to somehow tell it to recurse through sub-objects, but I don't know how to do it, or if that's even the problem. It seems weird that a serialization issue would cause a connection reset, and not an exception.


dotnet-csharpwindows-wcf
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

PengDing-MSFT avatar image
0 Votes"
PengDing-MSFT answered PengDing-MSFT edited

Hi @HaabFred-4575 , When you use collections polymorphically in place of non-collection types, they must be added to known types.

You need to add the following attributes on MyData:


     [CollectionDataContract]
     [KnownType(typeof(List<string>))]
     public class MyData : System.Collections.Generic.Dictionary<string, object> { }


The following figure is the result of the test using Postman:

72889-%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE-2021-03-01-153814.png

For more information about "Collection Types in Data Contracts", you can refer to this link.





If the answer is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

Best regards,
Peng Ding



5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.