在 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 方法返回 String
和 ResponseFormat = WebMessageFormat.Json
。它遵循字符串的 JSON 编码。对应于 www.json.org 字符串中的所有双引号将使用反斜杠进行转义。所以你目前有双重 JSON 编码。
返回任何类型数据的最简单方法是将GetCurrentCart()
web 方法的输出类型更改为Stream
或Message
(来自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/… 如何解决这个问题,它附加了我尝试了 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(字符串)的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Json.Net 从我的 WCF 休息服务(.NET 4)返回 json,而不是用引号括起来的字符串?
.Net WCF 返回的包含 JSON 的字符串以 \" 而不是简单的 "