【问题标题】:Avoid using the JsonIgnore attribute in a domain model避免在域模型中使用 JsonIgnore 属性
【发布时间】:2014-03-25 15:14:53
【问题描述】:

我有一个包含多个实体类的域模型组件。在另一个组件中,我有使用 Json.NET 序列化实现的实体存储库。我想在序列化过程中忽略一些实体属性,因此直接的解决方案是使用 JsonIgnore 属性装饰这些属性。但是,出于原则,我想避免在我的域模型中引用其他组件 - 包括 Json.NET 等 3rd 方库。

我知道我可以按照here 的描述创建自定义合同解析器,但是很难在各种实体中概括哪些要序列化和哪些不应该序列化。通常我想忽略所有只读属性,但也有例外,例如集合:

public List<Pixel> Pixels
{
    get { return this.Pixels; }
}

我还可以为每个实体创建一个专用的合同解析器,如 here 所述,但这对我来说似乎是一个需要大量维护的解决方案 - 特别是对于众多实体。

如果 Json.NET 支持 .NET 框架内的某些属性,理想的解决方案是,但我什至找不到合适的候选者...

我考虑过在我的域模型中创建自己的自定义 Ignore 属性,并创建一个使用反射来检测此属性并在序列化时忽略修饰属性的自定义合同解析器。但这真的是给定问题的最佳解决方案吗?

【问题讨论】:

    标签: c# .net json.net


    【解决方案1】:

    I believe by default that Json.net RespectsDataContractAttribute。虽然你必须包容而不是排斥,但这也意味着序列化可以更改为微软的二进制(或者可能是 xml),而不必重新设计你的域模型。

    如果一个类有很多属性,而您只想序列化其中的一小部分,那么将 JsonIgnore 添加到所有其他属性将是乏味且容易出错的。解决这种情况的方法是将 DataContractAttribute 添加到类中,将 DataMemberAttributes 添加到要序列化的属性中。这是选择加入序列化,与使用 JsonIgnoreAttribute 的选择退出序列化相比,仅对您标记的属性进行序列化。

    [DataContract]
    public class Computer
    {
      // included in JSON
      [DataMember]
      public string Name { get; set; }
      [DataMember]
      public decimal SalePrice { get; set; }
    
      // ignored
      public string Manufacture { get; set; }
      public int StockCount { get; set; }
      public decimal WholeSalePrice { get; set; }
      public DateTime NextShipmentDate { get; set; }
    }
    

    【讨论】:

      【解决方案2】:

      Json 序列化器也支持opt-in serialization:

      [JsonObject(MemberSerialization.OptIn)]
      public class File
      {
        // excluded from serialization
        // does not have JsonPropertyAttribute
        public Guid Id { get; set; }
      
        [JsonProperty]
        public string Name { get; set; }
      
        [JsonProperty]
        public int Size { get; set; }
      }
      

      来自Optin 枚举值文档:

      只有标有JsonPropertyAttributeDataMemberAttribute 的成员才会被序列化。这种成员序列化方式也可以通过DataContractAttribute标记类来设置。

      【讨论】:

      • 我喜欢这个,因为它内置在库中。跳过继承的属性也很好。
      【解决方案3】:

      您可以考虑使用视图模型之类的东西来控制您的实体模型的哪些属性被序列化。我自己没有使用它,但考虑将它用于我的一个项目,但 AutoMapper 可能是为了将实体模型与序列化模型解耦。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-19
        相关资源
        最近更新 更多