web-dev-qa-db-ja.com

WCFで生のJSON(文字列)を返す

私は自分の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は、それが気まぐれから出て行く原因となります。

「」の前に\を付けずに文字列を返すにはどうすればよいですか?

47
Paul Knopf

現在、WebメソッドはResponseFormat = WebMessageFormat.JsonとともにStringを返します。文字列のJSONエンコーディングに従います。 www.json.orgに対応し、文字列内のすべての二重引用符はバックスラッシュを使用してエスケープされます。そのため、現在、JSONエンコードは2倍になっています。

あらゆる種類のデータを返す最も簡単な方法は、GetCurrentCart() Webメソッドの出力タイプをStreamではなくMessageまたはStringSystem.ServiceModel.Channelsから)に変更することです。
を参照 http://blogs.msdn.com/b/carlosfigueira/archive/2008/04/17/wcf-raw-programming-model-web.aspxhttp://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));
}
109
Oleg

Olegが提案する方法を試しましたが、大量のデータにこの方法を使用すると、JSON文字列の最後にNULLキーが追加されることがわかりました。

例:大量のデータを持つjsonの場合{"JsonExample": "xxxxx"} null

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;
    }
5
Ivix4u

それは素晴らしく(Oleg Response)、すべてWebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset = utf-8";という行を追加することを確認してください。

削除した場合、結果はfileとしてダウンロードされます。

2
Ahmed Samir

Jil ライブラリを使用して、JSONオブジェクトまたはdynamic(ExpandoObject)をシリアル化することをお勧めします。

私の場合、常にJsonConvert.SerializeXXXから「{}」を取得し、JavaScriptSerializerから{aa:bb}を{key:aa、value:bb}に拡張するなど、null値の問題を回避します。

以下に完全なサンプルを示します。

インターフェース:

[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));
} 
2
John_J