C# 使用JSON序列化请求对象

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序列化HttpRequest的问题

背景

我最初认为我可以使用如下所示的方法轻松完成:

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

JSON.Encode(new {HttpContext.Request.Cookies,HttpContext.Request.Headers, ... });
这很好用

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

以前的方法

  • 使用反射遍历 请求并尝试构造JSON字符串 “逐财产”。(遇到通知时,此操作失败。) (参考)

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

  • 使用并尝试通过JsonConvert.SerializeObject()方法对其进行序列化(我已尝试传入几个附加设置以避免循环引用,但没有任何运气)

我的最新方法(使用JSON.NET库)我认为可以接近正常工作,但是我遇到了一个错误,该错误涉及请求中流对象的“Timeout”属性


我并不反对简单地避免序列化流对象和循环引用。我只是想尽可能多地获取请求对象,同时避免这些类型的灾难。

您不使用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无法转换具有流属性的对象。我也开始倾向于这种方式。序列化流时,它似乎会导致超时,然后输出前面提到的答案。我想我必须找到一种方法来忽略流/循环引用。