在 wcf 中返回原始 json(字符串)

Posted

技术标签:

【中文标题】在 wcf 中返回原始 json(字符串)【英文标题】:Returning raw json (string) in wcf 【发布时间】:2011-03-05 22:30:33 【问题描述】:

我想构建自己的 JSON,并让服务返回一个字符串,这是代码

[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
public string GetCurrentCart()

    //Code ommited
    string jsonClient = null;
    var j = new  Content = response.Content, Display=response.Display, SubTotal=response.SubTotal;
    var s = new javascriptSerializer();
    jsonClient = s.Serialize(j);
    return jsonClient;

我得到的响应包含 \" 用于在 c# 中的字符串中创建 "。

以下是回复。

"\"Content\":\"\\r\\n\\u003cdiv\\u003e\\r\\n\\u003cinput type=\\\"hidden\\\" name=\\\"__VIEWSTATE\\\" id=\\\"__VIEWSTATE\\\" value=\\\"\/wEPDwUBMA9kFgJmD2QWAmYPZBYGAgMPFgIeBFRleHQFKFlvdSBoYXZlIG5vIGl0ZW1zIGluIHlvdXIgc2hvcHBpbmcgY2FydC5kAgUPFgIeB1Zpc2libGVoZAIHDxQrAAIPFgIfAWhkZGQYAQUMY3RsMDEkbHZDYXJ0D2dkoWijqBUJaUxmDgFrkGdWUM0mLpgQmTOe8R8hc8bZco4=\\\" \/\\u003e\\r\\n\\u003c\/div\\u003e\\r\\n\\r\\n\\u003cdiv class=\\\"block block-shoppingcart\\\"\\u003e\\r\\n    \\u003cdiv class=\\\"title\\\"\\u003e\\r\\n        \\u003cspan\\u003eShopping Cart\\u003c\/span\\u003e\\r\\n    \\u003c\/div\\u003e\\r\\n    \\u003cdiv class=\\\"clear\\\"\\u003e\\r\\n    \\u003c\/div\\u003e\\r\\n    \\u003cdiv class=\\\"listbox\\\"\\u003e\\r\\n        You have no items in your shopping cart.\\r\\n        \\r\\n        \\r\\n    \\u003c\/div\\u003e\\r\\n\\u003c\/div\\u003e\\r\\n\",\"Display\":\"You have no items in your shopping cart.\",\"SubTotal\":null"

值被正确编码,但 json 本身的格式不正确。这些 \'s 导致它变得异常。

我如何返回一个字符串,在 "'s 前面没有 \'s?

【问题讨论】:

当我设置 ResponseFormat=WebMessageFormat.Xml 时,\'s 消失了,但当然根 xml 节点在那里(我不想要)。 【参考方案1】:

目前,您的 Web 方法返回 StringResponseFormat = WebMessageFormat.Json。它遵循字符串的 JSON 编码。对应于 www.json.org 字符串中的所有双引号将使用反斜杠进行转义。所以你目前有双重 JSON 编码。

返回任何类型数据的最简单方法是将GetCurrentCart() web 方法的输出类型更改为StreamMessage(来自System.ServiceModel.Channels)而不是String。 有关代码示例,请参阅 http://blogs.msdn.com/b/carlosfigueira/archive/2008/04/17/wcf-raw-programming-model-web.aspx、http://msdn.microsoft.com/en-us/library/ms789010.aspx 和 http://msdn.microsoft.com/en-us/library/cc681221(VS.90).aspx。

因为您没有在问题中写下您使用的是哪个版本的 .NET,所以我建议您使用通用且最简单的方法:

public Stream GetCurrentCart()

    //Code ommited
    var j = new  Content = response.Content, Display=response.Display,
                  SubTotal=response.SubTotal;
    var s = new JavaScriptSerializer();
    string jsonClient = s.Serialize(j);
    WebOperationContext.Current.OutgoingResponse.ContentType =
        "application/json; charset=utf-8";
    return new MemoryStream(Encoding.UTF8.GetBytes(jsonClient));

【讨论】:

我在这件事上浪费了很多时间。谢谢! 嗨,奥列格,谢谢你……我为此浪费了这么多时间,最后我找到了这个链接……真的谢谢你…… @Victor:我很高兴听到(阅读)我可以帮助你。不客气! 嗨,我还有一个问题,当我返回最后显示 null 的 json 字符串时,你可以参考这个链接一次吗restaurantmanager.testshell.net/api/Account/… 如何解决这个问题,它附加了 w3.org/2001/XMLSchema-instance" />【参考方案2】:

我尝试了 Oleg 建议的方法,但发现当我使用此方法处理大量数据时,JSON 字符串末尾附加了 null 关键字。

示例: 用于包含大量数据的 json "JsonExample":"xxxxx"null

在 http://wcf.codeplex.com/workitem/67 找到了解决此问题的解决方案 编写了以下函数,它将接受一个对象并返回一个纯 Json 输出。所以在主方法中返回我的对象​​之前,我调用了下面的方法。

  public HttpResponseMessage ReturnPureJson(object responseModel)
    
        HttpResponseMessage response = new HttpResponseMessage();

        string jsonClient = Json.Encode(responseModel);
        byte[] resultBytes = Encoding.UTF8.GetBytes(jsonClient);
        response.Content = new StreamContent(new MemoryStream(resultBytes));
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");

        return response;
    

【讨论】:

但除非你有 .NET 4.5,否则你不能使用 HttpResponseMessage【参考方案3】:

太好了(Oleg 回应) 并确保您添加该行 WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset=utf-8";

如果您删除它,结果将被下载为文件。

【讨论】:

【参考方案4】:

我建议使用Jil 库来序列化您的 JSON 对象或动态(ExpandoObject)。

在我的情况下,它将避免一些空值问题,比如总是从 JsonConvert.SerializeXXX 获取“”并将 aa:bb 从 JavaScriptSerializer 扩展到 key:aa, value:bb

完整示例如下。

界面:

[OperationContract]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "json/GetCurrentCart")]
Stream GetCurrentCart(MyRequestParam Param);

实施:

public Stream GetCurrentCart(MyRequestParam Param)

    //code omitted
    dynamic j = new System.Dynamic.ExpandoObject();
    j.Content = response.Content;
    j.Display = response.Display; 
    j.SubTotal = response.SubTotal;
    string s = Jil.JSON.SerializeDynamic(j);
    WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset=utf-8";
    return new MemoryStream(Encoding.UTF8.GetBytes(s));
 

【讨论】:

以上是关于在 wcf 中返回原始 json(字符串)的主要内容,如果未能解决你的问题,请参考以下文章

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

如何使用 Json.Net 从我的 WCF 休息服务(.NET 4)返回 json,而不是用引号括起来的字符串?

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

从 HTTPClient 响应中解压 GZip 流

如何在不使用查询字符串的情况下使用 WCF 在 UriTemplate 中传递 JSON 字符串

检查WCF是否有非常大的json字符串