使用JSON序列化请求对象

本文关键字:对象 请求 序列化 JSON 使用 | 更新日期: 2023-09-27 18:07:11

我目前正在进行概念验证,并遇到了一个涉及使用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库)我认为会接近工作,但是我遇到了一个错误,涉及请求中的流对象上的"超时"属性。

我不反对简单地避免序列化流对象和循环引用。我只是试图抓住尽可能多的请求对象,同时避免任何这些类型的事故。

使用JSON序列化请求对象

我只是尝试做同样的事情,我现在已经设法获得一些序列化使用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对象,我在哪里,所以这是在我的忽略属性列表-显然删除,如果你可以包括它!

你为什么不使用JSON.Net?它有一个名为PreserveReferencesHandling的设置,它用一个附加属性("$id":"##")标记对象。如果该对象在序列化中出现不止一次,它不会再次写入对象,而是用"$ref":"##"替换它,指向该对象已经存在的json。这规避了循环引用。

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

我在我的项目中使用了JsonConvert.SerializeObject,它工作得很好。它似乎可以解决你的问题。

JsonConvert.SerializeObject(reqObject)