13

現在、概念実証に取り組んでおり、JSON を使用して HttpRequest をシリアル化する際に問題が発生しました。

バックグラウンド

私は当初、以下に示すようにJSON.Encode()メソッドを使用して簡単に実現できると考えていました。

JSON.Encode(HttpContext.Request)

ただし、これによりあらゆる種類の循環参照がスローされることがすぐにわかりました (主に Request オブジェクトの実際の構造と複雑さが原因です)。これらは、循環参照を含むプロパティに実際に遭遇した場合にのみ発生します。これは、以前に次のコードを使用して必要な特定の要素だけを取得したためです。

JSON.Encode(new {HttpContext.Request.Cookies,HttpContext.Request.Headers, ... });

これは問題なく動作します。

これを処理するより良い方法があるかどうか(またはそれを処理する最良の方法は何か)、私はただ興味があります。私がこれまでに取ったアプローチのいくつかを以下で詳しく説明し、間違っている可能性のある領域を見つけられるようにします。

以前のアプローチ

  • リフレクションを使用してリクエスト内の各プロパティを繰り返し処理し、JSON 文字列「プロパティごと」の構築を試みます。(これは、循環参照に遭遇したときに失敗しました)

  • 各プロパティをディクショナリ オブジェクト内に格納しようとし、JSON を使用してディクショナリ全体をシリアル化します (オブジェクトを「フラット化」してシリアル化を容易にすることを期待して)

  • JSON.NET ライブラリを使用し、JsonConvert.SerializeObject() メソッドを介してシリアル化しようとしています (循環参照を回避するためにいくつかの追加設定を渡そうとしましたが、うまくいきませんでした)

私の最新のアプローチ ( JSON.NET ライブラリを使用) は、ほぼ機能すると思いましたが、リクエスト内のストリーム オブジェクトの「タイムアウト」プロパティに関連するエラーが発生しました。

Stream オブジェクトと循環参照のシリアル化を単純に回避することに反対しているわけではありません。これらのタイプの事故を回避しながら、できるだけ多くの Request オブジェクトを取得しようとしています。

4

3 に答える 3

8

私はちょうど同じことをしようとしました.JsonConvertとコントラクトリゾルバーを使用してシリアル化するものを取得し、すべての問題プロパティを無視することができました-シリアル化を行うためにこの行を使用しました:

string reqStr = JsonConvert.SerializeObject(context.Request,
    Formatting.Indented, new JsonSerializerSettings {
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
        ContractResolver = new IgnoreErrorPropertiesResolver()
});

そして、これが私が使用したコントラクト リゾルバー コードです。

public class IgnoreErrorPropertiesResolver : DefaultContractResolver
{

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);

        if (["InputStream",
            "Filter",
            "Length",
            "Position",
            "ReadTimeout",
            "WriteTimeout",
            "LastActivityDate",
            "LastUpdatedDate",
            "Session"
        ].Contains(property.PropertyName)) {
            property.Ignored = true;
        }
        return property;
    }
}

これは必要Newtonsoft.Json.Serializationであり、使用しSystem.Reflectionます。

私がいる場所にオブジェクトを含めることができない場合がSessionあるため、それは無視されたプロパティのリストに含まれています-含めることができる場合は明らかに削除してください!

于 2016-01-25T13:00:46.267 に答える
6

JSON.Net を使用していない特定の理由はありますか? という設定がありPreserveReferencesHandling、追加のプロパティ ("$id":"##") でオブジェクトにタグを付けます。そのオブジェクトがシリアライゼーションで複数回出現する場合、オブジェクトを再度書き込む代わりに、オブジェクトの既存の json を指す "$ref": "##" に置き換えます。これにより、循環参照が回避されます。

その形式の JSON を $.ajax 呼び出しに返そうとしたことがないので、Web 側での解析に何が関係するのかわかりません。

于 2013-04-02T04:36:39.557 に答える
4

私はJsonConvert.SerializeObject自分のプロジェクトで使用しましたが、正常に動作しています。あなたの問題を解決するかもしれません。

JsonConvert.SerializeObject(reqObject)
于 2013-10-21T20:31:01.603 に答える