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

如果我有一个CSON模型类,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”和“some_string”,这样我就可以动态地创建一个“&fields”参数。 谢谢!

@Leigh Shepperson有正确的想法; 但是,使用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()) .Select(jp => jp.PropertyName)); } 

你可以像这样使用它:

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

编辑

如果您在.Net Framework的3.5版本下运行,使得您没有可用的通用GetCustomAttribute方法,则可以使用非genericsGetCustomAttributes()方法执行相同的操作,使用它与SelectManyCast

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

你可以使用reflection来做到这一点。 这是一般的想法:

 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核心Web API); 否则使用DefaultContractResolver

样品小提琴 。