使用Json.net进行序列化时,如何更改属性名称?


434

我在C#DataSet对象中有一些数据。我现在可以使用像这样的Json.net转换器序列化它

DataSet data = new DataSet();
// do some work here to populate 'data'
string output = JsonConvert.SerializeObject(data);

但是,这将使用data打印到.json文件时的属性名称。我想将属性名称更改为其他名称(例如,将“ foo”更改为“ bar”)。

Json.net文档中的 “序列化和反序列化JSON”→“序列化属性”下,它显示“ JsonPropertyAttribute ...允许自定义名称”。但是没有例子。有谁知道如何使用JsonPropertyAttribute将属性名称更改为其他名称?

直接链接到文档

Json.net的文档似乎很少。如果您有一个很好的例子,我将尝试将其添加到官方文档中。谢谢!


3
仅供参考,文档中的示例->序列化JSON-> JsonPropertyAttribute name下有一个示例。不知道在什么时候添加了它。
Brian Rogers 2013年

Answers:


791

您可以使用[JsonProperty]允许您指定其他名称的属性来装饰希望控制其名称的属性:

using Newtonsoft.Json;
// ...

[JsonProperty(PropertyName = "FooBar")]
public string Foo { get; set; }

文档:序列化属性


1
这是否要求我将数据读入我创建的自定义对象而不是DataSet中?
culix 2012年

3
@culix,是的,它确实需要使用模型。DataSet是弱类型的结构,因此谈论其属性名称并不是很合逻辑。
达林·迪米特洛夫

76
作为简写,您也可以[JsonProperty("FooBar")]
Bart Verkoeijen

2
@DarinDimitrov如果没有Json .NET,有没有办法做到这一点?
CH81 2015年

12
不过,使用模型很容易,只需获取JSON示例,然后使用“选择性粘贴”->“将JSON作为类粘贴”将其粘贴到一个空的.cs文件中即可。-它内置在Visual Studio中。-从那里开始,您基本上只需要将其设置为标题大小写/重命名内容即可使用.NET命名约定等(对于前者使用标题大小写转换器,对于后者使用JsonProperty属性)。
BrainSlugs83 '16

71

如果您无权访问用于更改属性的类,或者不想始终使用相同的重命名属性,则也可以通过创建自定义解析程序来重命名。

例如,如果您有一个名为 MyCustomObject,具有一个名为的属性LongPropertyName,则可以使用这样的自定义解析器…

public class CustomDataContractResolver : DefaultContractResolver
{
  public static readonly CustomDataContractResolver Instance = new CustomDataContractResolver ();

  protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
  {
    var property = base.CreateProperty(member, memberSerialization);
    if (property.DeclaringType == typeof(MyCustomObject))
    {
      if (property.PropertyName.Equals("LongPropertyName", StringComparison.OrdinalIgnoreCase))
      {
        property.PropertyName = "Short";
      }
    }
    return property;
  }
}

然后调用序列化并提供解析器:

 var result = JsonConvert.SerializeObject(myCustomObjectInstance,
                new JsonSerializerSettings { ContractResolver = CustomDataContractResolver.Instance });

结果将缩短为 {“ Short”:“ prop value”}而不是{“ LongPropertyName”:“ prop value”}

有关自定义解析器的更多信息,请点击此处


1
如果要序列化的类是在另一个程序集中声明的,而该程序集包含另一个版本的Newtonsoft.Json包,则这是一个更好的解决方案。(它甚至可能不会引发任何错误)。在DefaultContractResolver必须把在使用JsonConvert.Serialize()方法相同的组件。
Artemious

6

还有另一种方式来做到这一点,这是使用特定NamingStrategy,其可以通过与装饰他们被应用到一个类或财产[JSonObject][JsonProperty]

有一些预定义的命名策略,例如CamelCaseNamingStrategy,但是您可以实现自己的命名策略。

可以在这里找到不同命名策略的实现:https : //github.com/JamesNK/Newtonsoft.Json/tree/master/Src/Newtonsoft.Json/Serialization


3
如果可以,请分享一个自定义NamingStrategy实现的示例
user1007074

当然不是。您应该自己完成此操作,但是我要花时间告诉您,您只需要继承newtonsoft.com/json/help/html / ...,您就可以看到现有的类实现,并创建自己的类。
JotaBe

谢谢-我应该更新我的评论:实际上,由于有了GitHub的荣耀,我们可以使用Newtonsoft自己的实现之一作为示例,例如,这个
user1007074

8
@JotaBe,这不是stackoverflow的精神。坦率地说,作为一个只想完成我的工作的程序员,对我来说,解除您可能提供的代码要好上千倍。您也会得到我的投票。我有18年的编码经验,在Triple C中,我被TripleByte评为“专家”。并非每个问题都需要留给读者“锻炼”。有时我们只是想做我们的工作并继续前进。
bboyle1234 '19

2
我同意你的看法,而且我通常不会写这种评论。但是,我可以保证,在这种情况下,查看链接的代码比我能给出的任何解释都要好。而且json.net是一个非常有据可查的开源库。包括指向实现的链接(完美示例)
JotaBe,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.