C# 使用JSON序列化请求对象
我目前正在进行概念验证,遇到了一个使用JSON序列化HttpRequest的问题 背景 我最初认为我可以使用如下所示的方法轻松完成:C# 使用JSON序列化请求对象,c#,asp.net-mvc,json,serialization,C#,Asp.net Mvc,Json,Serialization,我目前正在进行概念验证,遇到了一个使用JSON序列化HttpRequest的问题 背景 我最初认为我可以使用如下所示的方法轻松完成: JSON.Encode(HttpContext.Request) 然而,我很快发现这会导致抛出各种循环引用(主要是由于请求对象的实际结构和复杂性)。这些仅在实际遇到包含循环引用的属性时发生,因为我之前使用了以下代码来获取所需的特定元素: JSON.Encode(new {HttpContext.Request.Cookies,HttpContext.Reques
JSON.Encode(HttpContext.Request)
然而,我很快发现这会导致抛出各种循环引用(主要是由于请求对象的实际结构和复杂性)。这些仅在实际遇到包含循环引用的属性时发生,因为我之前使用了以下代码来获取所需的特定元素:
JSON.Encode(new {HttpContext.Request.Cookies,HttpContext.Request.Headers, ... });
这很好用
我只是好奇是否有更好的方法来处理这个问题(或者最好的处理方法是什么)。我将在下面详细介绍我迄今为止所采取的一些方法,以可能找到我可能出错的地方
以前的方法
- 使用反射遍历 请求并尝试构造JSON字符串 “逐财产”。(遇到通知时,此操作失败。) (参考)
- 尝试将每个属性存储在Dictionary对象中,然后使用JSON序列化整个Dictionary(希望它能“展平”对象并使序列化更容易)
- 使用并尝试通过JsonConvert.SerializeObject()方法对其进行序列化(我已尝试传入几个附加设置以避免循环引用,但没有任何运气)
我并不反对简单地避免序列化流对象和循环引用。我只是想尽可能多地获取请求对象,同时避免这些类型的灾难。您不使用JSON.Net的具体原因是什么?它有一个名为
PreserveReferencesHandling
的设置,该设置使用附加属性(“$id”:“##”)标记对象。如果该对象多次出现在序列化中,则不会再次写入该对象,而是将其替换为“$ref”:“##”指向该对象已有的json。这避免了循环引用
我从未尝试过将这种格式的JSON返回到$.ajax调用中,因此我不知道在web端解析它会涉及到什么。我在项目中使用了
JsonConvert.SerializeObject
,它工作得很好。看来它可以解决你的问题
JsonConvert.SerializeObject(reqObject)
我只是尝试做同样的事情,现在我已经成功地使用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
使用
碰巧我不能将
会话
对象包含在我所在的位置,因此它在我忽略的属性列表中-如果可以包含它,显然要删除它 谢谢你的建议,马尔科姆。自从阅读了您的建议并应用了一些设置之后,我尝试了几种不同的方法来使用它,但我仍然遇到一个问题,似乎是(主要与流有关?)“此流不支持流”。有什么想法吗?这让我觉得JSON无法转换具有流属性的对象。我也开始倾向于这种方式。序列化流时,它似乎会导致超时,然后输出前面提到的答案。我想我必须找到一种方法来忽略流/循环引用。