gpt4 book ai didi

c# - Json.net反序列化null guid案例

转载 作者:太空狗 更新时间:2023-10-29 18:11:50 24 4
gpt4 key购买 nike

我正在使用 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 中进行此转换。

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

  1. 创建一个 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); } }
    }
  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 类型的所有值.并且,要在全局范围内注册此类转换器,请参见例如 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()] 所示。 .

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

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com