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

cul*_*lix 415 c# serialization json.net

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

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

但是,这会data在打印到.json文件时使用属性名称.我想将属性名称更改为不同的名称(例如,将'foo'更改为'bar').

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

(直接链接到文档)

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

Dar*_*rov 759

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

using Newtonsoft.Json;
// ...

[JsonProperty(PropertyName = "FooBar")]
public string Foo { get; set; }
Run Code Online (Sandbox Code Playgroud)

文档:序列化属性

  • 作为简写,你也可以做`[JsonProperty("FooBar")]` (73认同)
  • 使用模型很简单,只需使用"粘贴特殊" - >"粘贴JSON作为类",将JSON样本并将其粘贴到空的.cs文件中. - 它内置于Visual Studio中. - 从那里,你基本上只需要设置标题大小写/重命名的东西来使用.NET命名约定等(前者使用标题大小写转换器,后者使用JsonProperty属性). (11认同)
  • @culix,是的,确实需要使用模型.DataSet是一种弱类型的结构,因此讨论它的属性名称并不合逻辑. (3认同)
  • @Homer在这种情况下不起作用,因为重点是能够使用与成员不同的名称。 (3认同)
  • 这是否需要我将数据读入我创建的自定义对象而不是数据集? (2认同)
  • @DarinDimitrov有没有办法在没有Json .NET的情况下做到这一点? (2认同)
  • 对于不依赖于 Json.NET(并且仍然适用于 Json.NET)的更通用的方法,您可以使用“DataMemberAttribute”,如“[DataMember(Name = "some_custom_string)]”。大多数序列化程序,包括内置的 Microsoft 序列化程序,知道如何处理此属性。 (2认同)

Sti*_*ack 69

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

例如,如果你有一个被调用的类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;
  }
}
Run Code Online (Sandbox Code Playgroud)

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

 var result = JsonConvert.SerializeObject(myCustomObjectInstance,
                new JsonSerializerSettings { ContractResolver = CustomDataContractResolver.Instance });
Run Code Online (Sandbox Code Playgroud)

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

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

  • 如果您要序列化的类是在包含不同版本的 Newtonsoft.Json 包的另一个程序集中声明的,则这是一个更好的解决方案。(它甚至可能不会抛出任何错误)。`DefaultContractResolver` 必须放在使用 JsonConvert.Serialize() 方法的同一个程序集中。 (3认同)
  • 我正在使用供应商的 API,该 API 具有由多个 API 函数使用的公共对象。仅在其中一个 API 调用中,公共对象的一个​​属性必须序列化为稍微不同的名称(例如 clientid 与 client_id)。这个答案完美地解决了我的问题。 (2认同)

Jot*_*aBe 5

还有另一种方法,可以使用特定的NamingStrategy,通过使用[JSonObject]或装饰它们可以将其应用于类或属性[JsonProperty]

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

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

  • @JotaBe,这不是stackoverflow的精神。坦白说,作为一个只想完成我的工作的程序员,对我来说,解除您可能提供的代码要好上千倍。您也会得到我的投票。我有18年的编码经验,在Triple C中,我被TripleByte评为“专家”。并非每个问题都需要留给读者“锻炼”。有时我们只是想做我们的工作并继续前进。 (6认同)
  • 我同意你的看法,我通常不会写这种评论。但是,我可以保证,在这种情况下,查看链接的代码比我能给出的任何解释都要好。json.net 是一个有据可查的开源库。包含实现的链接(完美示例) (5认同)
  • 谢谢 - 我应该更新我的评论:实际上,感谢 GitHub 的荣耀,可以使用 Newtonsoft 自己的实现之一作为示例,例如,[this one](https://github.com/JamesNK/Newtonsoft .Json/blob/master/Src/Newtonsoft.Json/Serialization/SnakeCaseNamingStrategy.cs) (3认同)
  • 如果可以,请分享一个自定义NamingStrategy实现的示例 (2认同)
  • 当然不是。你应该自己做,但我会花时间告诉你,你只需要继承 https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Serialization_NamingStrategy.htm 你可以看到现有的类实施,并创建自己的。 (2认同)