在JSON.NET中序列化派生类时的字段顺序 [英] Order of fields when serializing the derived class in JSON.NET

查看:146
本文介绍了在JSON.NET中序列化派生类时的字段顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下两个类:

public Class Base {
    public string Id {get; set;}
    public string Name {get; set;}
    public string LastName {get; set;}
}

以及派生类:

public Class Derived : Base {
    public string Address {get; set;}
    public DateTime DateOfBirth {get; set;}
}

使用 Json.Net 序列化派生类时:

Derived record = new Derived record(); {// Initialize here...}
JsonConvert.SerializeObject(record);

默认情况下,派生类的属性首先显示:

By default, the properties of the Derived class appear first:

{ 
  "address": "test", 
  "date_of_birth" : "10/10/10",
  "id" : 007,
  "name" : "test name",
  "last_name": "test last name"
 }

我需要什么:

{ 
  "id" : 007,
  "name" : "test name",
  "last_name": "test last name"
  "address": "test", 
  "date_of_birth" : "10/10/10",      
 }

问题

在序列化派生类时(两个类的每个属性都不使用[JsonProperty(Order=)] ),是否有可能使基类属性最先出现?

Is it possible to have the base class properties come first, when serializing the derived class (without using [JsonProperty(Order=)] for each property of both classes)?

推荐答案

根据 JSON标准(一个JSON对象)是名称/值对的无序集合.因此,我的建议是不要担心财产秩序.不过,您可以通过创建自己的 ContractResolver 来获得所需的订单.继承自标准合同解析器之一,然后覆盖 CreateProperties :

According to the JSON standard, a JSON object is an unordered set of name/value pairs. So my recommendation would be to not worry about property order. Nevertheless you can get the order you want by creating your own ContractResolver inheriting from one of the standard contract resolvers, and then overriding CreateProperties:

public class BaseFirstContractResolver : DefaultContractResolver
{
    // As of 7.0.1, Json.NET suggests using a static instance for "stateless" contract resolvers, for performance reasons.
    // http://www.newtonsoft.com/json/help/html/ContractResolver.htm
    // http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Serialization_DefaultContractResolver__ctor_1.htm
    // "Use the parameterless constructor and cache instances of the contract resolver within your application for optimal performance."
    static BaseFirstContractResolver instance;

    static BaseFirstContractResolver() { instance = new BaseFirstContractResolver(); }

    public static BaseFirstContractResolver Instance { get { return instance; } }

    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var properties = base.CreateProperties(type, memberSerialization);
        if (properties != null)
            return properties.OrderBy(p => p.DeclaringType.BaseTypesAndSelf().Count()).ToList();
        return properties;
    }
}

public static class TypeExtensions
{
    public static IEnumerable<Type> BaseTypesAndSelf(this Type type)
    {
        while (type != null)
        {
            yield return type;
            type = type.BaseType;
        }
    }
}

然后像这样使用它:

        var settings = new JsonSerializerSettings { ContractResolver = BaseFirstContractResolver.Instance };
        var json = JsonConvert.SerializeObject(derived, Formatting.Indented, settings);

这篇关于在JSON.NET中序列化派生类时的字段顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆