在 Json.Net 中序列化属性,但不要反序列化属性 [英] Serialize Property, but Do Not Deserialize Property in Json.Net
问题描述
虽然我找到了很多方法来反序列化特定属性,同时防止它们序列化,但我正在寻找相反的行为.
While I've found plenty of approaches to deserializing specific properties while preventing them from serializing, I'm looking for the opposite behavior.
我发现了很多相反的问题:
I've found plenty of questions asking the inverse:
JSON.Net - 仅使用 JsonIgnoreAttribute关于序列化(但不是在反序列化时)
如何序列化特定属性,但防止其反序列化回 POCO?是否有我可以用来装饰特定属性的属性?
How can I serialize a specific property, but prevent it from deserializing back to the POCO? Is there an attribute I can use to decorate the specific property?
基本上,我正在寻找与 ShouldSerialize* 方法等效的反序列化方法.
Basically I'm looking for an equivalent to the ShouldSerialize* methods for deserialization.
我知道我可以编写自定义转换器,但这似乎有点矫枉过正.
I know I can write a custom converter, but that seems like overkill for this.
这里有更多的上下文.这背后的原因是我的课程看起来像:
Here's a little more context. The reason behind this is my class looks like:
public class Address : IAddress
{
/// <summary>
/// Gets or sets the two character country code
/// </summary>
[JsonProperty("countryCode")]
[Required]
public string CountryCode { get; set; }
/// <summary>
/// Gets or sets the country code, and province or state code delimited by a vertical pipe: <c>US|MI</c>
/// </summary>
[JsonProperty("countryProvinceState")]
public string CountryProvinceState
{
get
{
return string.Format("{0}|{1}", this.CountryCode, this.ProvinceState);
}
set
{
if (!string.IsNullOrWhiteSpace(value) && value.Contains("|"))
{
string[] valueParts = value.Split('|');
if (valueParts.Length == 2)
{
this.CountryCode = valueParts[0];
this.ProvinceState = valueParts[1];
}
}
}
}
[JsonProperty("provinceState")]
[Required]
public string ProvinceState { get; set; }
}
我需要请求的 CountryProvinceState
属性,但我不希望它反序列化并触发 setter 逻辑.
I need the CountryProvinceState
property for the request, but I don't want it to deserialize back and trigger the setter logic.
推荐答案
最简单的方法是将不动产标记为 [JsonIgnore]
并创建一个 get-only 代理属性:
Simplest method would be to mark the real property as [JsonIgnore]
and create a get-only proxy property:
/// <summary>
/// Gets or sets the country code, and province or state code delimited by a vertical pipe: <c>US|MI</c>
/// </summary>
[JsonIgnore]
public string CountryProvinceState
{
get
{
return string.Format("{0}|{1}", this.CountryCode, this.ProvinceState);
}
set
{
if (!string.IsNullOrWhiteSpace(value) && value.Contains("|"))
{
string[] valueParts = value.Split('|');
if (valueParts.Length == 2)
{
this.CountryCode = valueParts[0];
this.ProvinceState = valueParts[1];
}
}
}
}
[JsonProperty("countryProvinceState")]
string ReadCountryProvinceState
{
get { return CountryProvinceState; }
}
如果您愿意,代理属性可以是私有的.
The proxy property can be private if you desire.
更新
如果您必须为许多类中的许多属性执行此操作,则创建自己的 ContractResolver
检查自定义属性.如果找到,该属性将表示该属性是仅获取的:
If you have to do this for lots of properties in lots of classes, it might be easier to create your own ContractResolver
that checks for a custom attribute. If found, the attribute would signal that the property is get-only:
[System.AttributeUsage(System.AttributeTargets.Property, AllowMultiple = false)]
public class GetOnlyJsonPropertyAttribute : Attribute
{
}
public class GetOnlyContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (property != null && property.Writable)
{
var attributes = property.AttributeProvider.GetAttributes(typeof(GetOnlyJsonPropertyAttribute), true);
if (attributes != null && attributes.Count > 0)
property.Writable = false;
}
return property;
}
}
然后像这样使用它:
[JsonProperty("countryProvinceState")]
[GetOnlyJsonProperty]
public string CountryProvinceState { get; set; }
然后:
var settings = new JsonSerializerSettings { ContractResolver = new GetOnlyContractResolver() };
var address = JsonConvert.DeserializeObject<Address>(jsonString, settings);
这篇关于在 Json.Net 中序列化属性,但不要反序列化属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!