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

时间:2023-04-25
本文介绍了序列化属性,但不要反序列化 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 的序列化字段的顺序 下一篇:如何使用 Json.Net 序列化/反序列化带有自定义键的字典?

相关文章