【问题标题】:Deserialize collection type virtual data member反序列化集合类型虚拟数据成员
【发布时间】:2018-03-21 06:27:01
【问题描述】:

我正在尝试将 json 反序列化为 RequestWithDefault 对象

JSON:

{
  "fields":["f1","f2"]
}

我的简单类图:

[DataContext]
public abstract class BaseRequest
{
  [DataMember]
  public virtual List<string> Fields { get; set; }
}

[DataContext]
public class RequestWithDefault : BaseRequest
{
  [DataMember]
  public override List<string> Fields {get; set; } = new List<string> {"test"}
}

将 json 反序列化为 RequestWithDefault 后,对象 Fields 属性包含 ["test", "f1", "f1"]。我想确保仅在请求中未指定 Fields 或指定为 null 时才应用此默认值。我怎么能做到这一点?我尝试使用 [OnDeserializing] 属性但没有成功。结果是一样的

据此: https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/collection-types-in-data-contracts 看起来像在反序列化期间 DataContractSerializer 从集合中调用 Add 方法。这就是为什么我也有默认值并添加了其余项目的原因。当我将 List&lt;string&gt; 替换为 string[] 时,一切正常。

【问题讨论】:

    标签: c# json datacontractserializer datamember


    【解决方案1】:

    似乎 WCF 序列化从不使用 setter 来设置具有集合类型的 DataMember 的值,而是使用 Add 代替。因此,检查fields 是否有任何值的唯一方法是在它被反序列化后检查(而不是在反序列化时)。

    [DataContext]
    public abstract class BaseRequest
    {
      [DataMember]
      public virtual List<string> Fields { get; set; }
    }
    
    [DataContext]
    public class RequestWithDefault : BaseRequest
    {
        [System.Runtime.Serialization.OnDeserialized]
        void OnDeserialized(System.Runtime.Serialization.StreamingContext c)
        {
            if (Fields == null
                || Fields.Count < 1)
            {
                Fields = new List<string> { "test" };
            }
        }
    }
    

    【讨论】:

    • 不知何故,如果我以这种方式实现它,则永远不会调用 setter。我总是得到默认值。
    • @Emil 我已经根据您的 cmets 更新了我的答案,我希望这个对您有用。
    • 它应该可以工作。在我发现 Serializer 根本不调用 setter 之后,我正在考虑这个解决方案。我将创建一些受保护的方法来设置默认值。谢谢
    猜你喜欢
    • 2010-11-14
    • 2018-08-05
    • 1970-01-01
    • 2017-01-09
    • 1970-01-01
    • 2010-09-15
    • 2014-06-07
    • 2020-03-09
    相关资源
    最近更新 更多