問題描述
我正在使用 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)null
a> 并且您將看到一條錯誤消息,指示無法在 .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:
創建一個
Guid?
可為空的代理屬性.如果您愿意,它可以是私有的,只要它具有[JsonProperty]
屬性:
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); } }
}
創建一個 JsonConverter
將 null
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 案例的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!