【问题标题】:How to set value of certain property on deserialization?如何在反序列化时设置某些属性的值?
【发布时间】:2021-11-22 05:30:59
【问题描述】:

我有一个类,其属性设置器依赖于VeryImportantProperty。但该属性不应按设计进行序列化。

所以,当我收到 JSON 时,我必须在反序列化期间和设置其他属性之前设置 VeryImportantProperty

我想可以通过修改ContractResolver来完成。我在那里存储VeryImportantProperty 的值,但我不知道如何分配它

我尝试使用以下ContractResolver,但不影响

public class MyContractResolver : DefaultContractResolver
{
    public VeryImportantClass VeryImportantPropertyValue { get; set; }
        
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);
            
        if (property.PropertyName == "VeryImportantProperty" && VeryImportantPropertyValue != null)
        {
            property.DefaultValue = VeryImportantPropertyValue;
            property.DefaultValueHandling = DefaultValueHandling.Populate;
            property.Order = -1;
        }

        return property;
    }
}

【问题讨论】:

  • VeryImportantProperty 的价值是多少?会根据同类的其他属性计算吗? ...还是在调用 Deserialize() 时必须提供的值?一个代码示例将有助于更好地理解问题。
  • @ChristophLütjen 我将在调用 Deserialize() 时提供值(例如将其设置为 ContractResolver 属性)
  • 请尝试与我们分享Minimal, Reproducible Example
  • 顺便说一句。听起来你只是有两个不同的模型。一个 dto 来表示 json 请求以及您在应用程序中需要的其他内容。可以选择为此简单地使用两个不同的类。
  • @ChristophLütjen 我愿意,但不幸的是,有成千上万个这样的遗留类。所以我必须寻找另一种解决方案

标签: c# .net serialization json.net


【解决方案1】:

我通过创建覆盖CreateContractContractResolverConverter 设置为覆盖Create 的自定义Create 以将我的VeryImportantProperty 传递给构造函数来解决了这个问题

代码:

public class MyContractResolver : DefaultContractResolver
{
    public VeryImportantClass VeryImportantPropertyValue { get; set; }

    protected override JsonContract CreateContract(Type objectType)
    {
        var contract = base.CreateContract(objectType);
        if (VeryImportantPropertyValue == null)
            return contract;

        // Solution for multiple classes is commented
        if (objectType == typeof(ContainerClass)/* || objectType.IsSubclassOf(typeof(BaseContainer))*/)
        {
            contract.Converter = new ImportantClassConverter(VeryImportantPropertyValue);
        }
        return contract;
    }

    private class ImportantClassConverter: CustomCreationConverter<VeryImportantClass>
    {
        public EntityConverter(VeryImportantClass veryImportantPropertyValue)
        {
            _veryImportantPropertyValue= veryImportantPropertyValue;
        }

        private readonly VeryImportantClass _veryImportantPropertyValue;

        public override VeryImportantClass Create(Type objectType)
        {
            // Might be simplified but it was used for multiple container classes with one parent
            return objectType.GetConstructor(new[] { typeof(ContainerClass) })
                ?.Invoke(new[] { _veryImportantPropertyValue }) as ContainerClass;
        }
    }
}

【讨论】:

    猜你喜欢
    • 2012-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多