【问题标题】:Returning raw json (string) in wcf在 wcf 中返回原始 json(字符串)
【发布时间】: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 节点在那里(我不想要)。

标签: wcf json


【解决方案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.aspxhttp://msdn.microsoft.com/en-us/library/ms789010.aspxhttp://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));
    } 
    

    【讨论】:

      猜你喜欢
      • 2013-11-29
      • 2020-06-29
      • 1970-01-01
      • 1970-01-01
      • 2015-09-03
      • 2023-04-05
      • 2014-06-07
      • 1970-01-01
      • 2020-02-08
      相关资源
      最近更新 更多