我正在使用 Json.NET
反序列化一个对象,该对象包含一个 Guid 类型的私有(private)字段和该字段的一个公共(public)属性。当我的 Guid
的值在我的 json 中为空时,我想将 Guid.Empty
分配给我的字段。
public class MyClass
{
private Guid property;
public Guid Property
{
get { return property; }
set
{
if (value == null)
{
property = Guid.Empty;
}
else
{
property = value;
}
}
}
}
但是反序列化器
想要访问私有(private)字段,导致我在尝试反序列化时得到这个错误:
Error converting value {null} to type 'System.Guid'. Path '[0].property', line 6, position 26.
如何让它忽略私有(private)字段而使用公共(public)属性?
最佳答案
Json.NET 拒绝为 Guid
设置 null
值,因为它是不可为 null 的值类型。尝试在 Immediate Window 中键入 (Guid)null
并且您将看到一条错误消息,指示无法在 .Net 中进行此转换。
要解决这个问题,您有几个选择:
创建一个
Guid?
可为 null 的代理属性。如果您愿意,它可以是私有(private)的,只要它有[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
类型的所有值.并且,要在全局范围内注册此类转换器,请参见例如 How to set custom JsonSerializerSettings for Json.NET in MVC 4 Web API? 对于 Web API, Setting JsonConvert.DefaultSettings asp net core 2.0 not working as expected 用于 ASP.NET Core 或 Registering a custom JsonConverter globally in Json.Net 用于控制台应用程序。如果您确实为控制台应用程序全局注册转换器,您可能需要为递归调用禁用它,如 JSON.Net throws StackOverflowException when using [JsonConvert()] 所示。 .
如果您只需要反序列化 Guid 的
null
值而不是重新序列化它,您可以申请[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
到 Guid 属性,null
值将被忽略,尽管它是无效的 Guid 值: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; }
请注意,如果 parameterized constructor在反序列化期间调用的具有同名的不可为 null 的 Guid 参数,可能需要不同的方法。
关于c# - Json.net反序列化null guid案例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31747712/