问题描述
虽然我找到了很多方法来反序列化特定属性同时防止它们被序列化,但我正在寻找相反的行为.
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
我可以指导 Json.NET 来反序列化而不是序列化特定属性?
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
属性,但我不希望它反序列化并触发设置器逻辑.
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
检查自定义属性.如果找到,该属性将表明该属性是 get-only:
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 中的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!