从 WCF 服务返回的 JSON 数据包含转义字符

Posted

技术标签:

【中文标题】从 WCF 服务返回的 JSON 数据包含转义字符【英文标题】:JSON data returned from WCF service contains escape characters 【发布时间】:2014-01-03 14:37:43 【问题描述】:

我有一个工作的 WCF - WPF 应用程序工作,但是我正在寻找一些优化。 下面是我的代码,其中 WCF RESTful 服务公开了一个 JSON 数组,而 WPF UI 正在接收它而没有任何问题。

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();

在 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();

    javascriptSerializer objJsonserialiser = new JavaScriptSerializer();

    objJsonserialiser.MaxJsonLength = 999999999;

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

    return new ObservableCollection<T>(arrResult);  


这种方式序列化/反序列化工作正常,而当我进行下面显示的更改时,反序列化不再起作用:

在 WCF 中:

public string[] GetAllStatus()

    DataTable dt = new DataTable();

    try
    
        dt = // My Data Table

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

    return jsonresp;

在 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 converting value \"[\"Id\":11280,\"statName]\" to type 'clsStat[]'. Path '', line 1, position 759."

我发现更改后的代码中的 JSON 格式包含转义字符 (\),这似乎是在反序列化时导致错误。

【问题讨论】:

dsReportRequests 是否实现了集合接口(例如ICollectionIList)? @franssu:没有。它不是。 dsReportRequests 仅包含 getter setter 属性。 【参考方案1】:

您的 JSON 正在被双重序列化。 (JSON 中多余的反斜杠就是这种情况的表现。)

请注意,在第一个版本中,您不会调用序列化 GetAllStatus() 中的返回对象,但在 InvokeGet() 中确实会调用反序列化它。那行得通。因此,GetAllStatus 的返回对象必须以某种方式自动序列化。应该清楚的是,WCF 必须为您处理返回对象的序列化。

在第二个版本中,您使用JsonConvert.SerializeObject() 手动序列化GetAllStatus() 中的返回对象。由于我们刚刚确定 WCF 也在进行序列化,因此您最终会得到双重序列化的 JSON。

要使其工作,您需要确保输出只被序列化一次。大概您有理由开始在您的服务中使用 Json.Net,所以我会寻找一种方法来用 JSON.Net 替换 WCF 序列化程序。您不必看得太远——*** 上有 quite a few questions and answers 处理这个主题。以下是一些想法:

replace WCF built-in JavascriptSerializer with Newtonsoft Json.Net json serializer(简介:编写自定义消息格式化程序并配置 WCF 以使用它) Replace default JSON serializer in WCF 4 to JSON.NET(简介:手动序列化为流,完全绕过 WCF 的序列化) WCF RESTful web service with JSON.Net: avoid double serialization(简介:使用 Web API 而不是 WCF,因为它已经默认使用 Json.Net)

【讨论】:

以上是关于从 WCF 服务返回的 JSON 数据包含转义字符的主要内容,如果未能解决你的问题,请参考以下文章

.Net WCF 返回的包含 JSON 的字符串以 \" 而不是简单的 "

服务器返回的json字符串,客户端解析为毛带转义字符“/”

从 HTTPClient 响应中解压 GZip 流

始终在 WCF 服务中返回带有 Json 的 XML 字符串

序列化包含转义(反斜杠和双引号)的 JSON 字符串 Swift 返回格式错误的对象

无法从启用 wcf json 的服务向客户端返回嵌套类型