13

我目前正在研究概念验证并遇到了一个涉及使用 JSON 序列化 HttpRequest 的问题。

背景

我最初认为我可以使用JSON.Encode()方法轻松完成它,如下所示:

JSON.Encode(HttpContext.Request)

但是,我很快发现这会导致抛出各种循环引用(主要是由于 Request 对象的实际结构和复杂性)。这些仅在实际遇到包含循环引用的属性时才会发生,因为我之前使用以下代码来获取我需要的特定元素:

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

效果很好。

我只是好奇是否有更好的方法来处理这个问题(或者最好的处理方法是什么)。我将在下面详细介绍到目前为止我所采取的一些方法,以找出我可能出错的任何地方。

以前的方法

  • 使用反射遍历请求中的每个属性,并尝试构造一个 JSON 字符串“property-by-property”。(遇到循环引用时失败

  • 尝试将每个属性存储在 Dictionary 对象中,然后使用 JSON 序列化整个 Dictionary (希望它将“扁平化”对象并使其更容易序列化

  • 使用JSON.NET 库并尝试通过 JsonConvert.SerializeObject() 方法对其进行序列化(我尝试传递几个额外的设置以避免循环引用,但没有任何运气

我认为我的最新方法(使用 JSON.NET 库)将接近工作,但是我遇到了一个错误,该错误涉及请求中 Stream 对象的“超时”属性。

我不反对简单地避免序列化 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.SerializationSystem.Reflection使用。

碰巧我不能包含Session我所在的对象,所以它在我的忽略属性列表中 - 如果你可以包含它,显然删除它!

于 2016-01-25T13:00:46.267 回答
6

您不使用 JSON.Net 的任何特殊原因?它有一个名为 的设置,它PreserveReferencesHandling使用附加属性(“$id”:“##”)标记对象。如果该对象多次出现在序列化中,则不会再次写入该对象,而是将其替换为“$ref”:“##”指向该对象的现有json。这绕过了循环引用。

我从来没有尝试过将这种格式的 JSON 返回到 $.ajax 调用,所以我不知道在 web 端解析它会涉及什么。

于 2013-04-02T04:36:39.557 回答
4

JsonConvert.SerializeObject在我的项目中使用过,它工作正常。看来它可以解决你的问题。

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