How to get the name of lt;Tgt; from generic type and pass it into JsonProperty()?(如何获得lt;Tgt;的名字从泛型类型并将其传递给 JsonProperty()?)
问题描述
下面的代码出现以下错误:
I get the following error with the code below:
"非静态字段、方法或属性 'Response.PropName'"
"An object reference is required for the non-static field, method, or property 'Response.PropName'"
代码:
public class Response<T> : Response
{
private string PropName
{
get
{
return typeof(T).Name;
}
}
[JsonProperty(PropName)]
public T Data { get; set; }
}
推荐答案
您尝试做的事情是可能的,但不是微不足道的,并且不能仅使用 JSON.NET 的内置属性来完成.您将需要一个自定义属性和一个自定义合同解析器.
What you're trying to do is possible, but not trivial, and can't be done with only the built-in attributes from JSON.NET. You'll need a custom attribute, and a custom contract resolver.
这是我想出的解决方案:
Here's the solution I came up with:
声明这个自定义属性:
[AttributeUsage(AttributeTargets.Property)]
class JsonPropertyGenericTypeNameAttribute : Attribute
{
public int TypeParameterPosition { get; }
public JsonPropertyGenericTypeNameAttribute(int position)
{
TypeParameterPosition = position;
}
}
将其应用于您的 Data 属性
Apply it to your Data property
public class Response<T> : Response
{
[JsonPropertyGenericTypeName(0)]
public T Data { get; set; }
}
(0是T在Response的泛型类型参数中的位置)
(0 is the position of T in Response<T>'s generic type parameters)
声明以下合约解析器,它将查找 JsonPropertyGenericTypeName 属性并获取类型参数的实际名称:
Declare the following contract resolver, which will look for the JsonPropertyGenericTypeName attribute and get the actual name of the type argument:
class GenericTypeNameContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var prop = base.CreateProperty(member, memberSerialization);
var attr = member.GetCustomAttribute<JsonPropertyGenericTypeNameAttribute>();
if (attr != null)
{
var type = member.DeclaringType;
if (!type.IsGenericType)
throw new InvalidOperationException($"{type} is not a generic type");
if (type.IsGenericTypeDefinition)
throw new InvalidOperationException($"{type} is a generic type definition, it must be a constructed generic type");
var typeArgs = type.GetGenericArguments();
if (attr.TypeParameterPosition >= typeArgs.Length)
throw new ArgumentException($"Can't get type argument at position {attr.TypeParameterPosition}; {type} has only {typeArgs.Length} type arguments");
prop.PropertyName = typeArgs[attr.TypeParameterPosition].Name;
}
return prop;
}
}
在您的序列化设置中使用此解析器进行序列化:
Serialize with this resolver in your serialization settings:
var settings = new JsonSerializerSettings { ContractResolver = new GenericTypeNameContractResolver() };
string json = JsonConvert.SerializeObject(response, settings);
这将为 Response<Foo>
{
"Foo": {
"Id": 0,
"Name": null
}
}
这篇关于如何获得<T>的名字从泛型类型并将其传递给 JsonProperty()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何获得<T>的名字从泛型类型并将其传递给 JsonProperty()?
基础教程推荐
- 在 VS2010 中的 Post Build 事件中将 bin 文件复制到物 2022-01-01
- 将事件 TextChanged 分配给表单中的所有文本框 2022-01-01
- 经典 Asp 中的 ResolveUrl/Url.Content 等效项 2022-01-01
- 全局 ASAX - 获取服务器名称 2022-01-01
- JSON.NET 中基于属性的类型解析 2022-01-01
- 错误“此流不支持搜索操作"在 C# 中 2022-01-01
- 如何动态获取文本框中datagridview列的总和 2022-01-01
- 是否可以在 asp classic 和 asp.net 之间共享会话状态 2022-01-01
- 首先创建代码,多对多,关联表中的附加字段 2022-01-01
- 从 VS 2017 .NET Core 项目的发布目录中排除文件 2022-01-01
