【问题标题】:Customise NewtonSoft.Json for Value Object serialisation [duplicate]为值对象序列化自定义 NewtonSoft.Json [重复]
【发布时间】:2017-05-04 10:58:36
【问题描述】:

有时,也许在 DDD 的情况下,您可能希望使用 C# 创建值对象来表示数据,以便为您的域赋予比使用原始类型更多的意义,并具有不可变的额外好处。

例如:

public class PostalCode // Bit like a zipcode
{
    public string Value { get; private set; }

    public PostalCode(string value)
    {
        Value = value;
    }

    // Maybe sprinkle some ToString()/Equals() overrides here
}

太棒了。干得好。

唯一的事情是,当序列化为 Json 时,你会得到:

{
    "Value": "W1 AJX"
}

这种看起来不错,但是当它用作对象的属性(比如说地址)时,它看起来像这样:

{
  "Line1": "Line1",
  "Line2": "Line2",
  "Line3": "Line3",
  "Town": "Town",
  "County": "County",
  "PostalCode": {
    "Value": "W1 AJX"
  }
}

极端一点,你可以看到这里有很多噪音。我想做的是告诉 Newtonsoft.Json,当它看到PostalCode 的类型时,它可以将其序列化为字符串值(反之亦然)。这将导致以下 json:

{
  "Line1": "Line1",
  "Line2": "Line2",
  "Line3": "Line3",
  "Town": "Town",
  "County": "County",
  "PostalCode": "W1 AJX"
}

这可以实现吗?我浏览了文档,我怀疑自定义 JsonConverter 可能是前进的方向?

【问题讨论】:

标签: c# serialization json.net


【解决方案1】:
public class PostalCode // Bit like a zipcode
{
    [JsonProperty(PropertyName = "PostalCode")]
    public string Value { get; set; }

    // Maybe sprinkle some ToString()/Equals() overrides here
}

我想这就是你的答案?

【讨论】:

  • 这是一个很好的答案,当然。虽然我宁愿避免将 json.net 属性洒在从技术上讲不知道诸如序列化之类的事情的类上。像这样使用的属性基本上是一个泄漏的抽象,尽管我很欣赏这个答案的简单性。
【解决方案2】:

您能利用implicit operator 语法吗?

https://msdn.microsoft.com/en-us/library/z5z9kes2.aspx

public class PostalCode
{
     public string Value { get; private set; }

     public PostalCode(string value)
     {
         this.Value = value;
     }

     public static implicit operator string(PostalCode result)
     {
         return result.Value;
     }
 }


var postCode = new PostalCode("WN11 2PZ");
Console.Output(postCode);  // "WN11 2PZ"

我还没有测试过这个,所以我可能会离开!

【讨论】:

  • 这如何改变 Newtonsoft JSON 序列化程序的行为?
  • 不会,但可能会导致序列化程序返回邮政编码字符串而不是新对象。
猜你喜欢
  • 2017-06-23
  • 2016-11-11
  • 1970-01-01
  • 2020-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多