[英]Json.net deserialization null guid case
我正在使用Json.NET
反序列化一个对象,该对象包含一个 Guid 类型的私有字段和该字段的一个公共属性。 当我的 json 中Guid
值为 null 时,我想将Guid.Empty
分配给我的字段。
public class MyClass
{
private Guid property;
public Guid Property
{
get { return property; }
set
{
if (value == null)
{
property = Guid.Empty;
}
else
{
property = value;
}
}
}
}
但是deserializer
想要访问私有字段,因为当我尝试反序列化时出现此错误:
将值 {null} 转换为类型“System.Guid”时出错。 路径“[0].property”,第 6 行,位置 26。
如何让它忽略私有字段并使用公共属性?
Json.NET 拒绝为Guid
设置null
值,因为它是不可为空的值类型。 尝试在立即窗口中键入(Guid)null
,您将看到一条错误消息,指出无法在 .Net 中进行此转换。
要解决此问题,您有几个选择:
创建Guid?
可为空的代理属性。 如果您愿意,它可以是私有的,只要它具有[JsonProperty]
属性:
public class MyClass { [JsonIgnore] public Guid Property { get; set; } [JsonProperty("Property")] Guid? NullableProperty { get { return Property == Guid.Empty ? null : (Guid?)Property; } set { Property = (value == null ? Guid.Empty : value.Value); } } }
创建一个JsonConverter
将null
Json 标记转换为默认 Guid 值:
public class NullToDefaultConverter<T> : JsonConverter where T : struct { public override bool CanConvert(Type objectType) { return objectType == typeof(T); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var token = JToken.Load(reader); if (token == null || token.Type == JTokenType.Null) return default(T); return token.ToObject(objectType); // Deserialize using default serializer } // Return false instead if you don't want default values to be written as null public override bool CanWrite { get { return true; } } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (EqualityComparer<T>.Default.Equals((T)value, default(T))) writer.WriteNull(); else writer.WriteValue(value); } }
然后将其应用于您的类型,如下所示:
public class MyClass { [JsonConverter(typeof(NullToDefaultConverter<Guid>))] public Guid Property { get; set; } }
或者,您可以通过将转换器添加到JsonSerializerSettings.Converters
来将转换器应用于T
类型的所有值。 并且,要全局注册这样的转换器,请参见例如如何在 MVC 4 Web API 中为 Json.NET 设置自定义 JsonSerializerSettings? 对于 Web API,设置 JsonConvert.DefaultSettings asp net core 2.0 无法按预期为 ASP.NET Core 工作或在 Json.Net 中为控制台应用程序全局注册自定义 JsonConverter 。
如果您确实为控制台应用程序全局注册转换器,则可能需要为递归调用禁用它,如使用 [JsonConvert()] 时 JSON.Net throws StackOverflowException 中所示。
如果您只需要反序列化 Guid 的null
值而不是将其重新序列化,则可以将[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
应用于 Guid 属性,并且尽管 Guid 值无效,但null
值将被忽略:
public class MyClass { [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public Guid Property { get; set; } }
当然,如果你这样做,你的 Guid 将被重新序列化为"00000000-0000-0000-0000-000000000000"
。 为了改善您可以应用DefaultValueHandling = DefaultValueHandling.Ignore
这将导致在序列化期间省略空 Guid 值:
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] public Guid Property { get; set; }
请注意,如果在反序列化期间调用的参数化构造函数具有同名的不可为空的 Guid 参数,则可能需要不同的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.