我正在试图弄清楚如何从我的API 返回一个核心对象
public class Response<T> {
public T Data {get;set;}
}
其中T是一些具有属性的对象,例如
public class Thang {
public string Thing {get;set;}
}
使用JsonConvert.Serialize( myResponse );
将返回T Data
属性作为Data
,这是正确的
但是,如果我想使用T
类型的名称呢?因此,响应Json实际上包括一个名为Thang
而不是Data
的属性,如下所示。
{
"thang": {
"thing" : "hey"
}
}
我很好奇Json.net是否有一种相对简单的方法可以做到这一点,或者在编写时必须创建一个自定义JsonConverter
并使用反射来获得T
类型名称?
谢谢。
据我所知,没有内置的方法可以做到这一点。
您确实需要使用一点反射,您可能会使用自定义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<Thang>
{
Data = new Thang { Thing = "Hey" }
}, settings);
可能更简单的做法是在序列化之前将类转换为Dictionary
我在确定封闭泛型类型上的属性是否对应于开放泛型类型的泛型属性时也遇到了一些小麻烦——如果有任何提示,我将不胜感激。
示例:https://dotnetfiddle.net/DejOL2