簡體   English   中英

調試 JsonConvert.SerializeObject 和對象引用未設置為對象的實例

[英]Debug JsonConvert.SerializeObject and object reference not set to an instance of an object

我似乎無法弄清楚為什么該方法“有時”會導致此空引用異常。 我在我的本地主機上運行代碼,當某些用戶出現這種情況時,它工作正常。 當我重新啟動站點時,它也會在服務器上消失。

我的問題是我該如何調試? 它采用 .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有一個屬性,它是對自身的引用,並且 JSON 序列化不支持循環引用。

您可以使用JsonIgnore Attribute裝飾您的o對象屬性,或者創建另一個沒有該屬性的類,或者如果您需要層次結構使用不會導致循環引用的不同對象。

如果這是一個模棱兩可的情況,日志記錄可能是追蹤違規對象的最快方法。

所以我能夠通過在復雜屬性上使用 ToJSON 來縮小范圍。 出於某種原因,實體框架將子列表存儲在緩存中的屬性上,而根本不應該這樣做,因為查詢在存儲到緩存中之前永遠不會拉出它。 我基本上告訴 automapper 忽略地圖上的這些屬性。

我通常喜歡使用 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;

}

如果出現錯誤,它將打印出未能加載的屬性。 根據用例,您可以“修復”它或使其失敗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM