Возврат raw json (string) в wcf
Я хочу создать свой собственный 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;
}
Ответ, который я получаю, содержит "используемый для создания" в строках в С#.
Ниже приведен ответ.
"{\"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 не отформатирован должным образом. Они заставляют его выходить из-под контроля.
Как вернуть строку без\перед "??
Ответы
Ответ 1
В настоящее время ваш веб-метод возвращает String
вместе с ResponseFormat = WebMessageFormat.Json
. Это следует за кодировкой JSON строки. Соответствует www.json.org. Все двойные кавычки в строке будут экранированы с помощью обратного слэша. Таким образом, в настоящее время вы используете двойную кодировку JSON.
Самый простой способ вернуть любые данные - изменить тип вывода веб-метода GetCurrentCart()
на 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));
}
Ответ 2
Я попробовал метод, предложенный Олегом, но обнаружил, что, когда я использовал этот метод для большого количества данных, в конце строки JSON было добавлено нулевое ключевое слово.
Пример: для json с большим количеством данных
{ "JsonExample": "ххххх" } нуль
найдено решение для решения этой проблемы по адресу: http://wcf.codeplex.com/workitem/67
Написал следующую функцию, которая примет объект и вернет выход Pure 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;
}
Ответ 3
Это было здорово ( Oleg Response) и все убедитесь, что вы добавили строку
WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset = utf-8";
если вы удалите его, результат будет загружен как файл.
Ответ 4
Я рекомендую использовать Jil
библиотеку для Serialize вашего объекта JSON или динамического (ExpandoObject).
В моем случае, это позволит избежать некоторой проблемы с нулевым значением, например, всегда получать "{}" из JsonConvert.SerializeXXX
и расширять {aa: bb} до {key: aa, value: bb} из JavaScriptSerializer
полный образец здесь, как показано ниже.
Интерфейс:
[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));
}