使用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库)我认为会接近工作,但是我遇到了一个错误,涉及请求中的流对象上的"超时"属性。
我不反对简单地避免序列化流对象和循环引用。我只是试图抓住尽可能多的请求对象,同时避免任何这些类型的事故。我只是尝试做同样的事情,我现在已经设法获得一些序列化使用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
对象,我在哪里,所以这是在我的忽略属性列表-显然删除,如果你可以包括它!
你为什么不使用JSON.Net?它有一个名为PreserveReferencesHandling
的设置,它用一个附加属性("$id":"##")标记对象。如果该对象在序列化中出现不止一次,它不会再次写入对象,而是用"$ref":"##"替换它,指向该对象已经存在的json。这规避了循环引用。
我从来没有尝试过以这种格式返回JSON到$。所以我不知道在web端解析它会涉及到什么
我在我的项目中使用了JsonConvert.SerializeObject
,它工作得很好。它似乎可以解决你的问题。
JsonConvert.SerializeObject(reqObject)