调试 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)
Try/Catch
我尝试了下面的方法,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
对象属性,或者创建另一个 class 而不使用 属性,或者如果您需要层次结构,请使用不同的不会导致循环引用的对象。
如果情况不明确,记录可能是追踪违规对象的最快方法。
因此,我能够通过对复杂属性使用 ToJSON 来缩小范围。出于某种原因 entity framework 将子列表存储在缓存中的 属性 上,而它根本不应该存储在缓存中,因为查询从不在存储到缓存中之前提取它。我基本上告诉 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;
}
如果出现错误,它将打印出加载失败的 属性。
根据用例,您可以“修复”它或使其失败。
我似乎无法弄清楚为什么方法“有时”会导致此空引用异常。我 运行 我的本地主机上的代码,当它出现在某些用户身上时它工作正常。当我重新启动网站时,它也会在服务器上消失。
我的问题是如何调试它?它采用 .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)
Try/Catch
我尝试了下面的方法,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
对象属性,或者创建另一个 class 而不使用 属性,或者如果您需要层次结构,请使用不同的不会导致循环引用的对象。
如果情况不明确,记录可能是追踪违规对象的最快方法。
因此,我能够通过对复杂属性使用 ToJSON 来缩小范围。出于某种原因 entity framework 将子列表存储在缓存中的 属性 上,而它根本不应该存储在缓存中,因为查询从不在存储到缓存中之前提取它。我基本上告诉 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;
}
如果出现错误,它将打印出加载失败的 属性。 根据用例,您可以“修复”它或使其失败。