JSON data returned from WCF service contains escape characters

六眼飞鱼酱① 提交于 2019-12-17 17:13:07

问题


I have a working WCF - WPF application working, however I'm looking for some optimization. Below is my code where a WCF restful service is exposing a JSON array, and a WPF UI is receiving it without any problem.

WCF:

public clsStatus[] GetAllStatus()
{

    DataTable dt = new DataTable();
    List<clsStatus> lstGetAllStatus = new List<clsStatus>();
    try
    {
        dt = // My Data Table

        foreach (DataRow dr in dt.Rows)
        {
            dcStatus objGetAllStatus = new clsStatus();
            objGetAllStatus.Id = Convert.ToInt32(dr["Id"]);
            objGetAllStatus.Status = dr["Status"].ToString();                   
            lstGetAllStatus.Add(objGetAllStatus);
        }

    }
    return lstGetAllStatus.ToArray();
}

In WPF UI:

public ObservableCollection<T> InvokeGet<T>(string sUrl)
{

    System.Net.WebRequest request = System.Net.HttpWebRequest.Create(sUrl);

    request.Method = "GET";

    request.UseDefaultCredentials = true;

    request.ContentLength = 0;

    System.Net.HttpWebResponse response = request.GetResponse() as System.Net.HttpWebResponse;

    Stream objResponseStream = response.GetResponseStream();

    StreamReader reader = new StreamReader(objResponseStream);

    string objResponseString = reader.ReadToEnd();

    response.Close();

    JavaScriptSerializer objJsonserialiser = new JavaScriptSerializer();

    objJsonserialiser.MaxJsonLength = 999999999;

    T[] arrResult = objJsonserialiser.Deserialize<T[]>(objResponseString);

    return new ObservableCollection<T>(arrResult);  

}

This way serialization/deserialization is working fine, whereas when I make the changes shown below the deserialization no longer works:

In WCF:

public string[] GetAllStatus()
{
    DataTable dt = new DataTable();

    try
    {
        dt = // My Data Table

        string jsonresp = JsonConvert.SerializeObject(dt, Formatting.None);
    }

    return jsonresp;
}

In WPF:

public ObservableCollection<T> InvokeGet<T>(string sUrl )
{

    System.Net.WebRequest request = System.Net.HttpWebRequest.Create(sUrl);

    request.Method = "GET";

    request.UseDefaultCredentials = true;

    request.ContentLength = 0;

    System.Net.HttpWebResponse response = request.GetResponse() as System.Net.HttpWebResponse;

    Stream objResponseStream = response.GetResponseStream();

    StreamReader reader = new StreamReader(objResponseStream);

    string objResponseString = reader.ReadToEnd();

    response.Close();

    dsReportRequests dsrepreq = new dsReportRequests();

    //This conversion is failing with error
    dsrepreq = JsonConvert.DeserializeObject<dsReportRequests>(objResponseString);
}

Error: "Error converting value \"[{\"Id\":11280,\"statName}]\" to type 'clsStat[]'. Path '', line 1, position 759."

I found out that the JSON format in the changed code contains escape chars (\), which seems to be causing the error while deserializing.


回答1:


Your JSON is getting double-serialized. (The extra backslashes in the JSON are symptomatic of this.)

Notice in the first version, you do not make a call to serialize the return object inside GetAllStatus(), but in InvokeGet() you do make a call to deserialize it. And that works. So, somehow the return object from GetAllStatus must be getting serialized automatically. It should be clear that WCF must be handling the serialization of your return object for you.

In the second version, you manually serialize the return object inside GetAllStatus() using JsonConvert.SerializeObject(). Since we just established that WCF is also doing serialization, you end up with double-serialized JSON.

To make it work, you need to ensure that the output is only serialized once. Presumably you had a reason to start using Json.Net in your service, so I would look for a way to replace the WCF serializer with JSON.Net. You don't have to look far-- there are quite a few questions and answers on StackOverflow that deal with this very topic. Here are few ideas:

  • replace WCF built-in JavascriptSerializer with Newtonsoft Json.Net json serializer (Synopsis: write a custom message formatter and configure WCF to use it)
  • Replace default JSON serializer in WCF 4 to JSON.NET (Synopsis: manually serialize to a stream and bypass WCF's serialization altogether)
  • WCF RESTful web service with JSON.Net: avoid double serialization (Synopsis: use Web API instead of WCF since it already uses Json.Net by default)


来源:https://stackoverflow.com/questions/20606952/json-data-returned-from-wcf-service-contains-escape-characters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!