获取属性的JsonPropertyAttribute

时间:2017-08-22 19:57:24

标签: c# reflection lambda properties json.net

我找到了一篇关于我遇到的问题的答案很好的帖子,但我似乎无法找到我正在寻找的小细节。

public class myModel
{
   [JsonProperty(PropertyName = "id")]
   public long ID { get; set; }
   [JsonProperty(PropertyName = "some_string")]
   public string SomeString {get; set;} 
}

我需要一个返回特定属性的JsonProperty PropertyName的方法。也许我可以通过我需要的TypeProperty,并且该方法返回值,如果找到的话。

以下是我发现的让我朝着正确方向前进的方法(我相信)taken from here

using System.Linq;
using System.Reflection;
using Newtonsoft.Json;
...

public static string GetFields(Type modelType)
{
    return string.Join(",",
        modelType.GetProperties()
                 .Select(p => p.GetCustomAttribute<JsonPropertyAttribute>()
                 .Where(jp => jp != null)
                 .Select(jp => jp.PropertyName));
}

目标是调用这样的函数(任何修改都可以)

string field = GetField(myModel, myModel.ID);

更新#1

我修改了上述内容,但我不知道如何从ID获取myModel.ID的字符串。

public static string GetFields(Type modelType, string field) {
    return string.Join(",",
        modelType.GetProperties()
            .Where(p => p.Name == field)
            .Select(p => p.GetCustomAttribute<JsonPropertyAttribute>())
            .Where(jp => jp != null)
            .Select(jp => jp.PropertyName)
        );
}

我想阻止硬编码实际属性名称的字符串。例如,我想要将上述方法称为:

string field = GetField(myModel, "ID");

我宁愿使用像

这样的东西
string field = GetField(myModel, myModel.ID.PropertyName);

但我不完全确定如何正确地做到这一点。

谢谢!

1 个答案:

答案 0 :(得分:2)

这是一种在保持强类型输入的同时执行此操作的方法:

public static string GetPropertyAttribute<TType>(Expression<Func<TType, object>> property)
{
    var memberExpression = property.Body as MemberExpression;
    if(memberExpression == null)
        throw new ArgumentException("Expression must be a property");

    return memberExpression.Member
        .GetCustomAttribute<JsonPropertyAttribute>()
        .PropertyName;
}

并称之为:

var result = GetPropertyAttribute<myModel>(t => t.SomeString);

你可以使它更通用,例如:

public static TAttribute GetPropertyAttribute<TType, TAttribute>(Expression<Func<TType, object>> property)
where TAttribute : Attribute
{
    var memberExpression = property.Body as MemberExpression;
    if(memberExpression == null)
        throw new ArgumentException("Expression must be a property");

    return memberExpression.Member
        .GetCustomAttribute<TAttribute>();
}

现在因为该属性是通用的,您需要将PropertyName调用移到外面:

var attribute = GetPropertyAttribute<myModel, JsonPropertyAttribute>(t => t.SomeString);
var result = attribute.PropertyName;