簡體   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