【问题标题】:Newtonsoft Json Serialisation of a Dictionary with custom properties具有自定义属性的字典的 Newtonsoft Json 序列化
【发布时间】:2016-02-03 11:01:08
【问题描述】:

我有以下 C# 代码,使用 Newtonsoft.Json v6.0.6:

void Main() {
    var data=new AllData();
    var cst=new CustomerData();
    cst.CustomerName="Customer1";
    cst.Add(1, new UserData() {UserName="User1", UserPhone="123456789"});
    cst.Add(2, new UserData() {UserName="User2", UserPhone="987654321"});
    data.Add(1, cst);

    string json = Newtonsoft.Json.JsonConvert.SerializeObject(data, Newtonsoft.Json.Formatting.Indented);
    Console.WriteLine(json);
}

public class UserData {
    public string UserName;
    public string UserPhone;
}

public class CustomerData:Dictionary<int,UserData> {
    public string CustomerName;
}

public class AllData:Dictionary<int,CustomerData> {}

所以我希望从这段代码中看到这个输出:

  {
    "1": {
      "CustomerName": "Customer1",
      "1": {
        "UserName": "User1",
        "UserPhone": "123456789"
      },
    "2": {
      "UserName": "User2",
      "UserPhone": "987654321"
      }
    }
  }

但我看到的是:

{
  "1": {
    "1": {
      "UserName": "User1",
      "UserPhone": "123456789"
    },
  "2": {
    "UserName": "User2",
    "UserPhone": "987654321"
    }
  }
}

即我的 CustomerName 属性被忽略。

我玩过 Newtonsoft.Json.MemberSerialization 和 Newtonsoft.Json.JsonProperty 属性但没有成功,所以想知道现在去哪里看。一个完整的自定义序列化实现似乎有点过头了,有没有简单的方法来解决这个问题?

【问题讨论】:

  • List&lt;T&gt;Dictionary&lt;T&gt; 继承被认为是代码异味。你有什么理由不继承Dictionary&lt;T&gt;就无法逃脱?
  • @AndyJ - 我知道自定义序列化,但似乎应该有一个更简单的方法,因此我的问题
  • @GediminasMasaitis 我可以拥有字典的属性,但这会使 Json 序列化更加复杂,因为我想省略属性名称。我可以有一个私有字典和我自己的访问器方法,但这会使我的示例复杂化,所以我选择继承来演示这个问题

标签: c# serialization json.net


【解决方案1】:

您可以使用 JSON.Net 提供的JsonExtensionDataAttribute 将父对象上不存在的任何属性放入集合属性中。

这是一个取自 another SO post 的示例。

JSON:

{
    "X" : "value",
    "key1": "value1",
    "key2": "value2"
}

C# 数据对象:

public class Test
{
    public string X { get; set; }

    [JsonExtensionData]
    public Dictionary<string, object> Y { get; set; }
}

Key1 和 Key2 最终会出现在 Dictionary 中,因为它们不存在于“Test”类中​​,而 X 将出现在 X 属性中。

这并不完美,看来您必须拥有 Dictionary 类型的 Dictionary,但使用自定义序列化程序可能是更好的选择?

这是一个example on DotNetFiddle,使用您的一级数据类。

对于数据:

public class UserData
{
    public string UserName;
    public string UserPhone;
}

public class CustomerData
{
    public string CustomerName;

    [JsonExtensionData]
    public Dictionary<string, object> Users;
}

var data = new CustomerData()
{
    CustomerName = "Foo",
    Users = new Dictionary<string, object>() 
    {
        { "1",  new UserData() { UserName = "Fireman", UserPhone = "0118 999 881 999 119 725 ... 3" } },
        { "2",  new UserData() { UserName = "Jenny", UserPhone = "867-5309" } }
    }
};

它生成 JSON:

{
    "customerName": "Foo",
    "1": {
        "userName": "Fireman",
        "userPhone": "0118 999 881 999 119 725 ... 3"
    },
    "2": {
        "userName": "Jenny",
        "userPhone": "867-5309"
    }
}

【讨论】:

  • 啊,谢谢你,我知道你可以如何使用它了。非常感谢@AndyJ,这是一个很好的解决方案 :-)
  • 没有问题,我很高兴你把它整理好了 :)
猜你喜欢
  • 1970-01-01
  • 2018-11-19
  • 2018-06-26
  • 1970-01-01
  • 2017-01-06
  • 1970-01-01
  • 1970-01-01
  • 2021-07-22
  • 1970-01-01
相关资源
最近更新 更多