【问题标题】:Debug JsonConvert.SerializeObject and object reference not set to an instance of an object调试 JsonConvert.SerializeObject 和对象引用未设置为对象的实例
【发布时间】:2021-01-31 03:22:28
【问题描述】:

我似乎无法弄清楚为什么方法“有时”会导致这个空引用异常。我在我的本地主机上运行代码,当它出现在某些用户身上时它工作正常。当我重新启动站点时,它也会在服务器上消失。

我的问题是如何调试它?它采用 .NET 对象并尝试对其进行序列化,但我无法确定是哪个属性导致了此问题。

方法

 public static string ToJSON(this object o)
        {
            return JsonConvert.SerializeObject(o, new JsonSerializerSettings
            {
               ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            });
        }

例外

     at System.Text.StringBuilder.Append(Char value)
   at Newtonsoft.Json.JsonTextWriter.WriteEnd(JsonToken token)
   at Newtonsoft.Json.JsonWriter.AutoCompleteClose(JsonContainerType type)
   at Newtonsoft.Json.JsonWriter.WriteEndObject()
   at Newtonsoft.Json.JsonWriter.WriteEnd(JsonContainerType type)
   at Newtonsoft.Json.JsonWriter.AutoCompleteAll()
   at Newtonsoft.Json.JsonTextWriter.Close()
   at Newtonsoft.Json.JsonWriter.Dispose(Boolean disposing)
   at Newtonsoft.Json.JsonWriter.System.IDisposable.Dispose()
   at Newtonsoft.Json.JsonConvert.SerializeObjectInternal(Object value, Type type, JsonSerializer jsonSerializer)
   at Newtonsoft.Json.JsonConvert.SerializeObject(Object value, JsonSerializerSettings settings)
   at Tournaments.Common.Extensions.ObjectExtensions.ToJSON(Object o)

尝试/抓住

我尝试了以下,JavascriptSerializer 抛出错误 A circular reference was detected while serializing an object of type 'Tournaments.Models.Events.EventModel'. 但是我不知道哪个对象有这个 EventModel,它可能是多个。

<script type="text/javascript">
        @{ 

            string model = null;
            try
            {
                model = Model.Designer.ToJSON();
            }
            catch (Exception ex )
            {
                model = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model.Designer);
            }
            }
            app.viewModel.members.bracket.init(@Html.Raw(model));
    </script>

【问题讨论】:

  • 你正在序列化的o是什么类型的对象,它的价值是什么?您应该注销此信息以获取有关问题所在的线索。
  • 很多属性和复杂对象的列表
  • 记录是一个很好的方法——甚至在 ToJSON() 中添加一个 try/catch 并在 catch 上设置一个断点;查看导致问题的对象的示例会很有帮助,即使还有其他对象也是如此。

标签: c# .net serialization json.net nullreferenceexception


【解决方案1】:

对象o 有一个属性是对其自身的引用,而 JSON 序列化不支持循环引用。

您可以使用 JsonIgnore Attribute 装饰您的 o 对象属性,或者创建另一个没有该属性的类,或者如果您需要层次结构,请使用不会导致循环引用的不同对象。

如果情况不明确,记录可能是追踪违规对象的最快方法。

【讨论】:

    【解决方案2】:

    所以我能够通过对复杂属性使用 ToJSON 来缩小范围。由于某种原因,实体框架将子列表存储在缓存中的属性上,而它根本不应该存储,因为查询在存储到缓存之前永远不会拉取它。我基本上告诉 automapper 忽略地图上的这些属性。

    【讨论】:

    • 很好,有什么代码可以为以后的人们备份它吗?
    【解决方案3】:

    我通常喜欢使用 Json 选项来处理这个问题

    我喜欢的选项

    static readonly JsonSerializerSettings _json = new JsonSerializerSettings()
    {
        Error = OnJsonError,
        DateFormatHandling = DateFormatHandling.IsoDateFormat,
        MissingMemberHandling = MissingMemberHandling.Ignore,
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
        NullValueHandling = NullValueHandling.Ignore,
        DefaultValueHandling = DefaultValueHandling.Ignore,
        ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
    };
    

    这是我的错误处理程序:

    private static void OnJsonError(object? sender, 
    Newtonsoft.Json.Serialization.ErrorEventArgs e)
    {
        if (e.CurrentObject is null)
        {
    
            _logger?.LogWarning("Serialization on {path} generated an exception {Error} with warning {Message}"
                , e.ErrorContext.Path
                , e.ErrorContext.Error.GetType().Name
                , e.ErrorContext.Error.Message
                );
        }
        else
        {
            _logger?.LogWarning("Serialization on {Name} had issues with path {Path} and generated an exception {Error} with warning {Message}"
                , e.CurrentObject.GetType().Name
                , e.ErrorContext.Path
                , e.ErrorContext.Error.GetType().Name
                , e.ErrorContext.Error.Message
                );
        }
        
        e.ErrorContext.Handled = true;
    
    }
    

    如果出现错误,它将打印出加载失败的属性。 根据用例,您可以“修复”它或使其失败。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多