0

WebApiコントローラーで次のアクションを記述しています。

public JsonResult GetData()
    {
        _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        var item = new Item();
        item.GenerateData();

        var jsonMediaTypeFormatter = new JsonMediaTypeFormatter
            {
                UseDataContractJsonSerializer = true
            };


        var jsonSerializer = new JsonSerializer();

        var serializedData = jsonSerializer.Serialize(jsonMediaTypeFormatter, item);

        var jsonResult = new JsonResult
        {
            ContentType = "application/json",
            Data = serializedData,
            JsonRequestBehavior = JsonRequestBehavior.AllowGet,
        };

        return jsonResult;
    }

次の行:var serializedData = jsonSerializer.Serialize(jsonMediaTypeFormatter、item);

データをJsonにシリアル化するため、次のようになります。

{"Class":{"Valid":{"From":"\/Date(1363302000000+0100)\/","To":"\/Date(43017433200000+0100)\/"},"Code":3,"Id":3,"Name":"Class3"},

など..(完全なJsonではありません)

ただし、JsonResultによって返されるJsonは異なります。

{"ContentEncoding":null,"ContentType":"application\/json","Data":"{\"Class\":{\"Valid\":{\"From\":\"\\\/Date(1363302000000+0100)\\\/\",\"To\":\"\\\/Date(43017433200000+0100)\\\/\"},\"Code\":3,\"Id\":3,\"Name\":\"Class3\"},

本文中の「」に注意してください。なぜそうなのですか?どのように変更するのですか?わかりません。

JsonSerializerの編集JsonSerializerは、DataContractJsonSerializerを使用してデータをJsonにシリアル化するヘルパークラスであり、そのコードは次のとおりです。

public class JsonSerializer
{
    public string Serialize<T>(MediaTypeFormatter formatter, T value)
    {
        // Create a dummy HTTP Content.
        Stream stream = new MemoryStream();
        var content = new StreamContent(stream);

        // Serialize the object.
        formatter.WriteToStreamAsync(typeof(T), value, stream, content, null).Wait();

        // Read the serialized string.
        stream.Position = 0;
        return content.ReadAsStringAsync().Result;
    }
}

私が欲しいのは、その実行の結果であり、変更されることなく、ユーザーに返されます

4

3 に答える 3

4

JsonResult中に入れたものはすべてDataJSONにすでにシリアル化されています。

コードは設定前に手動でJSONにシリアル化されますData。これにより、出力に二重シリアル化されたオブジェクトが含まれます(item最初に手動でJSON文字列にシリアル化され、次に文字列がJSONルールを使用して再度シリアル化されます。この2番目のシリアル化がエスケープされます。引用符)。

技術的には、二重シリアル化が意図的に行われる可能性を排除することはできませんが、おそらくあなたがすべきことは

var jsonResult = new JsonResult
    {
        ContentType = "application/json",
        Data = item,
        JsonRequestBehavior = JsonRequestBehavior.AllowGet,
    };

2回シリアル化する必要はないが、手動でシリアル化する必要がある場合は、ContentResult代わりに次を使用してください。

return new ContentResult
       {
           ContentType = "application/json",
           Content = serializedData,
       };
于 2013-03-15T12:45:09.203 に答える
0

二重引用符はエスケープされます。これは意図された動作であり、望ましい動作でもあります。文字列(JSONデータを保持する文字列など)が早期に閉じられるのを防ぎます。

于 2013-03-15T12:45:45.910 に答える
0

結果オブジェクトを作成する組み込みJson()メソッドを使用してみませんか?

public JsonResult GetData()
{
    _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    var item = new Item();
    item.GenerateData();

    return Json(item);
}

シリアル化の実行方法を詳細に制御する必要がある場合は、独自のバージョンのJsonResultクラスを作成してオーバーライドExecute()できます。その投稿は、Json()メソッドをオーバーライドするコントローラーの基本クラスを作成することも提案していますが、私はむしろ拡張メソッドを作成したいと思いますController-一つには、これは基本クラスに関してコントローラーに要件を課しません、そして別の必要に応じて、デフォルトの動作を非表示にしません。

public static class ControllerExtensions
{
     public static JsonResult DataContractJson(this Controller ctrl, object data) {
         return new DataContractJsonResult { Data = data };
     }
}

この答え(上記と同じ質問に対する)は、あなたがしていることを正確に達成しているようです-データコントラクト属性を処理できるJSONシリアライザーを選択します。

于 2013-03-15T13:21:49.560 に答える