在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类

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

默认情况下, Derived类的属性首先出现:

 { "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=)]两个类的每个属性使用[JsonProperty(Order=)] )?

根据JSON标准 ,JSON对象是一组无序的名称/值对 。 所以我的建议是不要担心房产秩序。 不过,您可以通过创建自己的ContractResolverinheritance其中一个标准合约解析器 ,然后覆盖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 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 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); 

只是为了补充,另一种不同于接受答案的方法是使用[JsonProperty(Order = -2)] ; 您可以修改基类,如下所示:

 public class Base { [JsonProperty(Order = -2)] public string Id { get; set; } [JsonProperty(Order = -2)] public string Name { get; set; } [JsonProperty(Order = -2)] public string LastName { get; set; } } 

将顺序设置为-2的原因是没有显式顺序的任何属性默认为-1。 因此,您必须为所有子属性提供一个订单,或者只是将基类的属性设置为-2。

如果您使用的是ASP.NET Core,请不要覆盖默认情况下提供的重要合同解析程序设置。 从@ dbc的回答开始,你可以这样做:

 class DataContractJsonResolver : DefaultContractResolver { public DataContractJsonResolver() { NamingStrategy = new CamelCaseNamingStrategy(); } protected override IList CreateProperties( Type type, MemberSerialization memberSerialization ) { return base.CreateProperties( type, memberSerialization ) .OrderBy( p => BaseTypesAndSelf( p.DeclaringType ).Count() ).ToList(); IEnumerable BaseTypesAndSelf( Type t ) { while ( t != null ) { yield return t; t = t.BaseType; } } } }