Json.net 反序列化 null guid 案例

Json.net deserialization null guid case(Json.net 反序列化 null guid 案例)

本文介绍了Json.net 反序列化 null guid 案例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Json.NET 反序列化一个对象,该对象包含一个 Guid 类型的私有字段和该字段的公共属性.当我的 Guid 在我的 json 中的值为 null 时,我想将 Guid.Empty 分配给我的字段.

I'm deserializing an object using Json.NET that contains a private field of type Guid and a public property for that field. When the value for my Guid is null in my json I want to assign Guid.Empty to my field.

public class MyClass
{
    private Guid property;
    public Guid Property
    {
        get { return property; }
        set 
        {
            if (value == null)
            {
                property = Guid.Empty;
            }
            else
            {
                property = value;
            }
        }
    }
}

但是 deserializer 想要访问私有字段,导致我在尝试反序列化时收到此错误:

But the deserializer wants to access the private field, cause I get this error when I try to deserialize:

将值 {null} 转换为类型System.Guid"时出错.小路'[0].property',第 6 行,第 26 位.

Error converting value {null} to type 'System.Guid'. Path '[0].property', line 6, position 26.

如何让它忽略私有字段而使用公共属性?

How can I make it ignore the private field and use the public property instead?

推荐答案

Json.NET 拒绝为 Guid 设置 null 值,因为它是不可为空的值类型.尝试在 即时窗口 中输入 (Guid)nulla> 并且您将看到一条错误消息,指示无法在 .Net 中进行此转换.

Json.NET refuses to set a null value for a Guid because it is a non-nullable value type. Try typing (Guid)null in the Immediate Window and you will see an error message indicating that this conversion cannot be made in .Net.

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

To work around this, you have a couple of options:

  1. 创建一个 Guid? 可为空的代理属性.如果您愿意,它可以是私有的,只要它具有 [JsonProperty] 属性:

  1. Create a Guid? nullable proxy property. It can be private if you desire as long as it has a [JsonProperty] attribute:

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); } }
}

  • 创建一个 JsonConverternull Json 令牌转换为默认 Guid 值:

  • Create a JsonConverter that converts a null Json token to a default Guid value:

    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);
        }
    }
    

    然后将其应用于您的类型,如下所示:

    Then apply it to your type as follows:

    public class MyClass
    {
        [JsonConverter(typeof(NullToDefaultConverter<Guid>))]
        public Guid Property { get; set; }
    }
    

    或者,您可以通过将转换器添加到 T 类型的所有值.htm" rel="noreferrer">JsonSerializerSettings.Converters.而且,要在全球范围内注册这样的转换器,请参阅例如如何在 MVC 4 Web API 中为 Json.NET 设置自定义 JsonSerializerSettings? 用于 Web API,设置 JsonConvert.DefaultSettings asp net core 2.0 无法正常工作 用于 ASP.NET Core 或 在 Json.Net 中全局注册自定义 JsonConverter对于控制台应用程序.

    Alternatively, you can apply the converter to all values of type T by adding the converter to JsonSerializerSettings.Converters. And, to register such a converter globally, see e.g.How to set custom JsonSerializerSettings for Json.NET in MVC 4 Web API? for Web API, Setting JsonConvert.DefaultSettings asp net core 2.0 not working as expected for ASP.NET Core or Registering a custom JsonConverter globally in Json.Net for a console app.

    如果您为控制台应用程序全局注册转换器,您可能需要禁用它以进行递归调用,如 JSON.Net 在使用 [JsonConvert()] 时抛出 StackOverflowException.

    If you do register the converter globally for a console app, you may need to disable it for recursive calls as shown in JSON.Net throws StackOverflowException when using [JsonConvert()].

    如果您只需要 反序列化 Guid 的 null 值而不是重新序列化它,则可以应用 [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 到 Guid 属性, 和 null 值将被忽略,尽管 Guid 值无效:

    If you only need to deserialize a null value for a Guid and not re-serialize it as such, you can apply [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] to the Guid property, and null values will ignored despite being invalid Guid values:

    public class MyClass
    {
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public Guid Property { get; set; }
    }
    

    当然,如果您这样做,您的 Guid 将被重新序列化为 00000000-0000-0000-0000-000000000000".为了改善这种情况,您可以应用 DefaultValueHandling = DefaultValueHandling.Ignore 这将导致在序列化期间省略空的 Guid 值:

    Of course if you do this your Guid will be re-serialized as "00000000-0000-0000-0000-000000000000". To ameliorate that you could apply DefaultValueHandling = DefaultValueHandling.Ignore which will cause empty Guid values to be omitted during serialization:

    [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
    public Guid Property { get; set; }
    

    请注意,如果在反序列化期间调用的 参数化构造函数具有非-nullable Guid 参数具有相同的名称,可能需要不同的方法.

    Note that if a parameterized constructor called during deserialization has a non-nullable Guid argument with the same name, a different approach may be required.

    这篇关于Json.net 反序列化 null guid 案例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

  • 本文标题为:Json.net 反序列化 null guid 案例