Json.NET在序列化上获得通用属性类型名称?

我试图弄清楚如何从我的API返回一个核心对象

public class Response { public T Data {get;set;} } 

其中T是具有属性的某个对象,例如

 public class Thang { public string Thing {get;set;} } 

使用JsonConvert.Serialize( myResponse );T Data属性作为Data返回,这是正确的。

但是,如果我想使用T的类型名称呢? 因此响应Json实际上会包含一个名为Thang not Data的属性,如下所示。

 { "thang": { "thing" : "hey" } } 

我很好奇是否有一个相对简单的方法来使用Json.net,或者您是否必须创建自定义JsonConverter并使用reflection来获取写入时的T类型名称?

谢谢。

我知道没有内置的方法来做到这一点。

您确实需要使用一点reflection,并且您可能使用自定义JsonConverter ,但您也可以使用自定义ContractResolver在几行代码中执行此操作:

 public class GenericPropertyContractResolver : CamelCasePropertyNamesContractResolver { private readonly Type genericTypeDefinition; public GenericPropertyContractResolver(Type genericTypeDefinition) { this.genericTypeDefinition = genericTypeDefinition; } protected override JsonProperty CreateProperty( MemberInfo member, MemberSerialization memberSerialization) { JsonProperty baseProperty = base.CreateProperty(member, memberSerialization); Type declaringType = member.DeclaringType; if (!declaringType.IsGenericType || declaringType.GetGenericTypeDefinition() != this.genericTypeDefinition) { return baseProperty; } Type declaringGenericType = declaringType.GetGenericArguments()[0]; if (IsGenericMember(member)) { baseProperty.PropertyName = this.ResolvePropertyName(declaringGenericType.Name); } return baseProperty; } // Is there a better way to do this? Determines if the member passed in // is a generic member in the open generic type. public bool IsGenericMember(MemberInfo member) { MemberInfo genericMember = this.genericTypeDefinition.GetMember(member.Name)[0]; if (genericMember != null) { if (genericMember.MemberType == MemberTypes.Field) { return ((FieldInfo)genericMember).FieldType.IsGenericParameter; } else if (genericMember.MemberType == MemberTypes.Property) { PropertyInfo property = (PropertyInfo)genericMember; return property .GetMethod .ReturnParameter .ParameterType .IsGenericParameter; } } return false; } } 

然后你可以像这样使用它:

 var settings = new JsonSerializerSettings(); settings.ContractResolver = new GenericPropertyContractResolver(typeof(Response<>)); string serialized = JsonConvert.SerializeObject(new Response { Data = new Thang { Thing = "Hey" } }, settings); 

可能更直接的做法是在序列化之前将类转换为Dictionary

我在确定封闭generics类型上的属性是否与开放generics类型的通用属性相对应时也遇到了一些麻烦 – 任何提示都将受到赞赏。

示例: https //dotnetfiddle.net/DejOL2