简体   繁体   English

C# JSON.NET 如何在反序列化而不是序列化中忽略属性

[英]C# JSON.NET How to ignore a property in deserialization but not in serialization

I have an object I am serializing into JSON then deserializing back.我有一个对象,我将其序列化为 JSON,然后反序列化回来。

The structure of one of the properties has changed and now deserializing crashes, so I need to ignore deserializing that property for now.其中一个属性的结构发生了变化,现在反序列化崩溃了,所以我现在需要忽略反序列化该属性。

I can ignore the property completely with [JsonIgnore, JsonProperty(Required = Required.Default)] , but that also ignores the property from serialization - which needs to stay so no data is lost, even if it isn't' being serialized at this moment.我可以使用[JsonIgnore, JsonProperty(Required = Required.Default)]完全忽略该属性,但这也会忽略序列化中的属性 - 它需要保留,因此不会丢失任何数据,即使它没有在此被序列化片刻。

There is an answer here, although it's a bit old: https://stackoverflow.com/a/31732029/12431728 However, it still seems viable to me, I'm not aware of a better / different way to do it.这里有一个答案,虽然它有点旧: https : //stackoverflow.com/a/31732029/12431728但是,它对我来说似乎仍然可行,我不知道有更好/不同的方法来做到这一点。 That answer suggests marking the real property with JsonIgnore and creating a "get-only proxy property."该答案建议使用 JsonIgnore 标记不动产并创建“仅获取代理属性”。

Then it goes on to suggest creating a custom ContractResolver if you need this functionality for many properties (AKA reusable solution).然后它继续建议创建一个自定义的 ContractResolver,如果您需要为许多属性使用此功能(AKA 可重用解决方案)。

You could use a JsonContractResolver to set the JsonProperty.ShouldDeserialize property as seen in one of the test suites of Newtonsoft.Json.您可以使用 JsonContractResolver 设置JsonProperty.ShouldDeserialize属性,如 Newtonsoft.Json 的测试套件之一所示。

For Example,例如,

public class ShouldDeserializeContractResolver : DefaultContractResolver
{
    public static new readonly ShouldDeserializeContractResolver Instance = new ShouldDeserializeContractResolver();

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);

        MethodInfo shouldDeserializeMethodInfo = member.DeclaringType.GetMethod("ShouldDeserialize" + member.Name);

        if (shouldDeserializeMethodInfo != null)
        {
            property.ShouldDeserialize = o => { return (bool)shouldDeserializeMethodInfo.Invoke(o, null); };
        }

        return property;
    }
}

Example Code示例代码

var instance = new RootObject { ID = 2, DisplayName = "John Doe" };
var json = JsonConvert.SerializeObject(instance);
var settings = new JsonSerializerSettings
{
  ContractResolver = ShouldDeserializeContractResolver.Instance
};
Console.WriteLine(json);

var deserializedInstance = JsonConvert.DeserializeObject<RootObject>(json, settings);
Console.WriteLine($"Deserialized => Id={deserializedInstance.ID}, Name={deserializedInstance.DisplayName} ");

Where RootObject is defined as其中 RootObject 定义为

public class RootObject
{
    public int ID { get; set; }
    public string DisplayName { get; set; }

    public bool ShouldDeserializeDisplayName() => false;    
}

Output输出

{"ID":2,"DisplayName":"John Doe"}  //During Serialization
Deserialized => Id=2, Name=        // During Deserialization  

You could serialise and deserialise from a JObject as in the link from Amadeu Antunes, although this solution is rather inelegant, as suddenly you've thrown loose typing into the mix.您可以从 Amadeu Antunes 的链接中对 JObject 进行序列化和反序列化,尽管此解决方案相当不优雅,因为您突然间将松散的输入混为一谈。

Another potentially easier possibility is that if you have access to all of the json objects that you are deserialising from, you could do a bulk update in notepad++, ssms or whatever and just add in some default value into the json files.另一个可能更简单的可能性是,如果您可以访问所有反序列化的 json 对象,您可以在 notepad++、ssms 或其他任何内容中进行批量更新,只需将一些默认值添加到 json 文件中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM