从类中获取要在查询字符串中使用的JSON属性名列表



如果我有一个C#模型类,它被JSON.net用来绑定来自序列化JSON字符串的数据,那么有没有办法从该类创建查询字符串来进行初始请求?

模型类示例:

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

查询字符串示例:

baseUrl + uri + "&fields=id,some_string" + token

因此,我尝试做的本质是从模型对象中收集"id"one_answers"some_string",这样我就可以动态地创建一个"&fields"参数。谢谢

@Leigh Sheppern有正确的想法;但是,您可以使用LINQ用更少的代码来实现这一点。我会创建一个像这样的辅助方法:

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>())
                 .Select(jp => jp.PropertyName));
}

你可以这样使用它:

var fields = "&fields=" + GetFields(typeof(model));

编辑

如果您在3.5版本的.Net Framework下运行,因此您没有通用的GetCustomAttribute<T>方法,那么您可以使用非通用的GetCustomAttributes()方法来做同样的事情,将其与SelectManyCast<T>:一起使用

    return string.Join(",",
        modelType.GetProperties()
                 .SelectMany(p => p.GetCustomAttributes(typeof(JsonPropertyAttribute))
                                   .Cast<JsonPropertyAttribute>())
                 .Select(jp => jp.PropertyName)
                 .ToArray());

您可以使用反射来完成此操作。这是总体思路:

using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Reflection;
namespace ConsoleApplication8
{
    public class model
    {
        [JsonProperty(PropertyName = "id")]
        public long ID { get; set; }
        [JsonProperty(PropertyName = "some_string")]
        public string SomeString { get; set; }
    }
    internal class Program
    {
        private static void Main(string[] args)
        {
            var model = new model();
            var result = string.Empty;
            PropertyInfo[] props = typeof(model).GetProperties();
            foreach (PropertyInfo prop in props)
            {
                foreach (object attr in prop.GetCustomAttributes(true))
                {
                    result += (attr as JsonPropertyAttribute).PropertyName;
                }
            }
        }
    }
}

如果模型仅用[JsonProperty(PropertyName = "XXX")]属性进行了部分注释,或者用数据协定属性进行了注释,或者忽略了属性,则可以使用Json.NET自己的协定解析器来获取序列化属性名称的列表。首先,介绍以下扩展方法:

public static class JsonExtensions
{
    public static string [] PropertyNames(this IContractResolver resolver, Type type)
    {
        if (resolver == null || type == null)
            throw new ArgumentNullException();
        var contract = resolver.ResolveContract(type) as JsonObjectContract;
        if (contract == null)
            return new string[0];
        return contract.Properties.Where(p => !p.Ignored).Select(p => p.PropertyName).ToArray();
    }
}

然后,做:

// Allocate the relevant contract resolver. 
// Options are CamelCasePropertyNamesContractResolver() or DefaultContractResolver().
IContractResolver resolver = new DefaultContractResolver(); 
// Get properties
var propertyNames = resolver.PropertyNames(typeof(model));
var fields = "&fields=" + String.Join(",", propertyNames);

对于resolver,如果您是属性名称的大小写,请使用CamelCasePropertyNamesContractResolver(默认情况下,ASP.NET Core Web API是这样做的);否则使用CCD_ 8。

样品小提琴。

解决空异常问题的@Brian Rogers解决方案的一个小变体:

IEnumerable<string> props = typeof(T).GetProperties()
                                     .Select(p => p.GetCustomAttribute<JsonPropertyAttribute>())
                                     .Where(jp => jp != null)
                                     .Select(jp => jp.PropertyName);
string propsList = string.Join(',', props);
public class CreateContactProperties
{
   [JsonProperty("email")] public string email { get; set; }
   [JsonProperty("firstname")] public string firstname { get; set; }
}
public string GetJsonPropertyFieldName(PropertyInfo t)
{
   var attr = t.GetCustomAttributes(typeof(JsonPropertyAttribute), true).FirstOrDefault() as JsonPropertyAttribute;
   return attr.PropertyName;
}

IList<PropertyInfo> entityprops = new List<PropertyInfo>(typeof(CreateContactProperties).GetProperties());
foreach (var item in entityprops)
{
  properties += $"{GetJsonPropertyFieldName(item)}, ";
}

相关内容

  • 没有找到相关文章

最新更新