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.