序列化属性,但不要反序列化 Json.Net 中的属性

Serialize Property, but Do Not Deserialize Property in Json.Net(序列化属性,但不要反序列化 Json.Net 中的属性)

本文介绍了序列化属性,但不要反序列化 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

我可以指导 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 中的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:序列化属性,但不要反序列化 Json.Net 中的属性

基础教程推荐