获取属性的 JsonPropertyAttribute

RoL*_*LLs 4 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;} 
}
Run Code Online (Sandbox Code Playgroud)

我需要一个返回JsonProperty PropertyName特定属性的方法。也许我可以传递Type和Property我需要的东西,如果找到,该方法将返回该值。

这是我找到的方法,它使我朝着正确的方向(我相信)从这里获取

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));
}
Run Code Online (Sandbox Code Playgroud)

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

string field = GetField(myModel, myModel.ID);
Run Code Online (Sandbox Code Playgroud)

更新 #1

我修改了上面的这个,但我不知道如何获取IDfrom的字符串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)
        );
}
Run Code Online (Sandbox Code Playgroud)

我想防止实际属性名称的硬编码字符串。例如,我不希望调用上面的方法为:

string field = GetField(myModel, "ID");
Run Code Online (Sandbox Code Playgroud)

我宁愿使用类似的东西

string field = GetField(myModel, myModel.ID.PropertyName);
Run Code Online (Sandbox Code Playgroud)

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

谢谢!

Dav*_*idG 7

这是一种在保持强类型的同时做到这一点的方法:

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;
}
Run Code Online (Sandbox Code Playgroud)

并这样称呼它:

var result = GetPropertyAttribute<myModel>(t => t.SomeString);
Run Code Online (Sandbox Code Playgroud)

你可以让它更通用一点,例如:

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>();
}
Run Code Online (Sandbox Code Playgroud)

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

var attribute = GetPropertyAttribute<myModel, JsonPropertyAttribute>(t => t.SomeString);
var result = attribute.PropertyName;
Run Code Online (Sandbox Code Playgroud)