在自定义字典中使用列表时,C# HttpService JSON 序列化会导致连接重置

问题描述

注意:我重新编辑了整篇文章,以提供最简单的版本。

我正在创建一个仅返回数据的简单 Web 服务,但与大多数 JSON 数据一样,可以有不同类型的层次结构。下面是代码一个简短示例:

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;
        }
}

如上所述,当我尝试从外部客户端(我使用 Postman 进行测试)或什至从任何浏览器访问它时,我收到连接重置错误。我在 VS 中以调试模式运行它,没有抛出异常,只是失败了。

但是,如果我注释掉有问题的行(就在返回之前),它会正确返回 JSON 序列化数据:

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

现在,我可以强制使用不同的序列化程序 - 如果我使用 JavaScriptSerializer,它创建的字符串是正确的,但是 WebInvoke 正在执行另一个隐式序列化,这意味着客户端需要反序列化两次才能正确获取数据。这是非常不雅观的。如果我可以告诉 WebInvoke 不序列化(如 Webmessageformat.Bare,但它不存在),它也可以工作。

最终我觉得我需要以某种方式告诉它通过子对象递归,但我不知道该怎么做,或者这是否是问题所在。序列化问题会导致连接重置,而不是异常,这似乎很奇怪。

以防万一,这里是启动/停止服务的类:

class HTTPService
{
    private WebServiceHost host = null;
    private ServiceEndpoint endpoint = null;
    private Logger logger = Logger.GetInstance;

    public Boolean StartService(
        ref JSONReceiver receiver,string URI)
    {
        Boolean rval = false;
        if (URI != null)
        {
            Uri uri = new Uri(URI);
            receiver = new JSONReceiver();
            host = new WebServiceHost(receiver,uri);
            WebHttpBinding binding = new WebHttpBinding();
            endpoint = host.AddServiceEndpoint(
                typeof(IJSONReceiver),binding,"");
            try
            {
                host.open();
                logger.Log(
                    String.Format("Started running on {0}",URI),MyLog.LogLevels.Debugging);
                rval = true;
            }
            catch (Exception e)
            {
                logger.Log(
                    String.Format("HTTPService: {0}",e.Message),MyLog.LogLevels.Errors);
            }
        }
        return rval;
    }

    public void StopService()
    {
        if(host != null)
        {
            try
            {
                host.Close();
            }
            catch
            {
                // ignore errors on close
            }
        }
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)