繁体   English   中英

Json.net 反序列化 null guid 案例

[英]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 中进行此转换。

要解决此问题,您有几个选择:

  1. 创建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); } } }
  2. 创建一个JsonConverternull 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 中所示。

  3. 如果您只需要序列化 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM