Err Connection Reset Using WebInvoke JSON - Serialization problem.

Haab, Fred 1 Reputation point
2021-02-27T17:54:12.117+00:00

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.

.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,337 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,192 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Peng Ding-MSFT 91 Reputation points
    2021-03-01T07:43:14.967+00:00

    Hi @Haab, Fred , 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

    0 comments No comments