[英]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 中進行此轉換。
要解決此問題,您有幾個選擇:
創建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); } } }
創建一個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
類型的所有值。 並且,要全局注冊這樣的轉換器,請參見例如如何在 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 中所示。
如果您只需要反序列化 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.