虽然我找到了很多方法来反序列化特定属性,同时防止它们序列化,但我正在寻找相反的行为.
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 序列化
我可以指导 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 属性,但我不希望它反序列化并触发 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 中序列化属性,但不要反序列化属性
发布评论