Newtonsoft JsonSerializer - 小写属性和字典

Lie*_*ero 52 c# json.net

我正在使用json.net(Newtonsoft的JsonSerializer).我需要自定义序列化以满足以下要求:

  1. 属性名称必须以小写字母开头.
  2. 必须将字典序列化为jsonp,其中键将用于属性名称.LowerCase规则不适用于字典键.

例如:

var product = new Product();
procuct.Name = "Product1";
product.Items = new Dictionary<string, Item>();
product.Items.Add("Item1", new Item { Description="Lorem Ipsum" });
Run Code Online (Sandbox Code Playgroud)

必须序列化为:

{
  name: "Product1",
  items : {
    "Item1": {
       description : "Lorem Ipsum"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

注意属性Name序列化为"name",但键Item1序列化为"Item1";

我试图创建CustomJsonWriter来序列化属性名称,但它也改变了dicionary键.

public class CustomJsonWriter : JsonTextWriter
{
    public CustomJsonWriter(TextWriter writer) : base(writer)
    {

    }
    public override void WritePropertyName(string name, bool escape)
    {
        if (name != "$type")
        {
            name = name.ToCamelCase();
        }
        base.WritePropertyName(name, escape);
    }
}
Run Code Online (Sandbox Code Playgroud)

Cra*_* W. 111

你可以尝试使用CamelCasePropertyNamesContractResolver.

var serializerSettings = new JsonSerializerSettings();
serializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
var json = JsonConvert.SerializeObject(product, serializerSettings);
Run Code Online (Sandbox Code Playgroud)

我只是不确定它将如何处理字典键,我没有时间在第二次尝试它.如果它没有正确处理密钥,那么仍然值得记住未来,而不是编写自己的自定义JSON编写器.

  • 小心这个选项.此选项还会导致序列化词典的小写键.这通常不是所期望的. (10认同)
  • 如果只希望将框应用于一个对象,则可以使用:`var json = JsonConvert.SerializeObject(product,new JsonSerializerSettings {ContractResolver = new CamelCasePropertyNamesContractResolver(),Formatting = Formatting.Indented});` (7认同)
  • 最简单、最可靠的解决方案是使用 [`NamingStrategy`](https://www.newtonsoft.com/json/help/html/NamingStrategySkipDictionaryKeys.htm) 来处理这些情况。它公开了细粒度选项,您可以使用这些选项对序列化进行驼峰命名法,而不必使用属性标记污染类,也不必冒在错误的位置应用驼峰命名法的风险。 (5认同)
  • 这个问题的答案说明了如何使用小写来实现自己的ContractResolver./sf/ask/440206231/ (2认同)

Bri*_*arm 47

您可以使用JsonProperty来更改某些内容的序列化/反序列化.定义对象时,将属性项添加到要在JSON中以不同方式表示的字段中.这仅适用于NewtonsoftJSON.其他图书馆可能采用不同的方式

public class Product
{
    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("items")]
    public Dictionary<string, Item> Items { get; set; }
}

public class Item
{
    [JsonProperty("description")]
    public string Description { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

  • 这不违反.它提供了在处理数据序列化时可能需要的映射.这是由于C#变量名称与底层序列化格式不匹配 - 不仅限于JSON. (10认同)
  • 好吧,如果有可以用来确定映射的规则或约定,那么它违反了 DRY (2认同)
  • 在这种情况下,知识是属性名称和用于序列化的约定.但由于您同时指定了属性名称和相关的序列化属性名称,因此它们不会保持同步.在您的示例中,更改一个元素需要(属性名称)需要更改另一个元素(序列化属性名称).显然违反DRY (2认同)