C# 从类中获取要在查询字符串中使用的JSON属性名称列表
如果我有一个C#model类,JSON.net使用该类绑定序列化JSON字符串中的数据,那么有没有一种方法可以从该类创建查询字符串以发出初始请求 模型类示例:C# 从类中获取要在查询字符串中使用的JSON属性名称列表,c#,json,json.net,.net-3.5,query-string,C#,Json,Json.net,.net 3.5,Query String,如果我有一个C#model类,JSON.net使用该类绑定序列化JSON字符串中的数据,那么有没有一种方法可以从该类创建查询字符串以发出初始请求 模型类示例: public class model { [JsonProperty(PropertyName = "id")] public long ID { get; set; } [JsonProperty(PropertyName = "some_string")] public string SomeString {g
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
查询字符串示例:
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”参数。谢谢 您可以使用反射来完成此操作。这是总体思路:
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;
}
}
}
}
}
@利·谢泼森的想法是正确的;但是,使用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));
编辑
如果您在.Net Framework的3.5版本下运行,因此没有通用的GetCustomAttribute
方法可用,则可以使用非通用的GetCustomAttributes()
方法,将其与SelectMany
和Cast
一起使用:
返回string.Join(“,”,
modelType.GetProperties()
.SelectMany(p=>p.GetCustomAttributes(typeof(JsonPropertyAttribute))
.Cast())
.Select(jp=>jp.PropertyName)
.ToArray());
如果模型仅使用[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
如果要使用驼峰式大小写,请使用属性名称(ASP.NET Core Web API就是这样做的);否则使用
示例。解决空异常问题的@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);
IEnumerable props=typeof(T).GetProperties()
.Select(p=>p.GetCustomAttribute())
.Where(jp=>jp!=null)
.Select(jp=>jp.PropertyName);
string-propsList=string.Join(“,”,props);
谢谢Brian,这是一个真正优雅的解决方案。我应该在问题中做得更好,我会在这次会议后更新。我使用的是Unity3D,即修改后的.net 3.5,似乎4.5中的getcustomattributes被赋予了泛型类型。您的问题最初被标记为Unity3D
,但由于问题似乎与此无关,我将其删除并在其位置添加了Json.net
。我已经更新了我的答案,向您展示了如何在.NET 3.5.Perfect中使用非泛型的GetCustomAttributes()
方法来做同样的事情,谢谢。只是在最后一个select语句后添加了一个.toArray()。@RoLYroLLs-您的编辑不正确;它跳过了没有[JsonProperty(PropertyName=“XXX”)]
属性的属性,而不是返回c#属性名称。你真的应该问另一个关于这种情况的问题,但是我补充了在这种情况下该怎么做。谢谢你,我将尝试在我的问题中使用这个