从类中获取要在查询字符串中使用的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()
方法执行相同的操作,使用它与SelectMany
和Cast
:
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
。
样品小提琴 。