本文介绍了如何获得< T>的名称从泛型类型并将其传递到JsonProperty()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在以下代码中收到以下错误:

I get the following error with the code below:

代码:

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属性

public class Response<T> : Response
{
    [JsonPropertyGenericTypeName(0)]
    public T Data { get; set; }
}

(0是TResponse<T>通用类型参数中的位置)

(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
  }
}

这篇关于如何获得&lt; T&gt;的名称从泛型类型并将其传递到JsonProperty()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 15:08