将匿名对象的属性和值转换为字典

问题描述:

我正在为现有API创建一个库。我目前有每个请求类的QueryParameter类。 QueryParameter类很简单,但它们有所不同(不是所有的请求都采用相同的查询参数)。将匿名对象的属性和值转换为字典

这里是一个QueryParameter类的例子:

public class ApiRequestAQueryParameters 
{ 
    public string Name { get; set; } 
    public int Start { get; set; } 
    public int Stop { get; set; } 
} 

我感兴趣的方式来这样的类转换成一个字典,我可以养活我们的Web客户端。我希望能有这样一个可重复使用的方法:

private Dictionary<string, string> GenerateQueryParameters(object queryParametersObject) 
{ 
// perform conversion 
} 

这样我就不必拔出QueryParameter性质为每个请求(会有几十请求)

,我的理由使用QueryParameter类而不是使QueryParameter成为每个API请求类的Dictionary属性是开发者友好的。我想要让其他人可以通过查看这些类来构建这些API请求。

有2种方法:1)使用反射和2)序列化到JSON和回。

这里是第一个方法:

private Dictionary<string, string> GenerateQueryParameters(object queryParametersObject) 
{ 
    var res = new Dictionary<string, string>(); 
    var props = queryParametersObject.GetType().GetProperties(); 
    foreach (var prop in props) 
    { 
     res[prop.Name] = prop.GetValue(queryParametersObject).ToString(); 
    } 
    return res; 
} 

你可以做这样的事情:

private Dictionary<string, string> GenerateQueryParameters(object queryParameters) 
{ 
    var startStop = new StartStop() { Start = queryParameters.Start, Stop = queryParameters.Stop}; 
    var result = new Dictionary<string, string>(); 
    result.Add(queryParameters.Name, startStop); 
    return result; 
} 

public class StartStop 
{ 
    public int Start { get; set; } 
    public int Stop { get; set; } 
} 

这可能是利用ExpandoObjects完美的情况。 ExpandoObject是一个动态类型,其属性可以在运行时创建。 ExpandoObject实现IDictionary <字符串,对象>因此很容易将其转换为字典< string,object>。

在下面的示例中,将创建ExpandoObject并将其转换为字典< string,object>,然后转换为字典< string,string>。

dynamic apiVar = new ExpandoObject(); 
apiVar.Name = "Test"; 
apiVar.Start = 1; 
apiVar.Stop = 2; 

var iDict = (IDictionary<string, object>) apiVar; 
/* if you can utilize a Dictionary<string, object> */ 
var objectDict = iDict.ToDictionary(i => i.Key, i => i.Value); 
/* if you need a Dictionary<string, string> */ 
var stringDict = iDict.ToDictionary(i=>i.Key, i=> i.Value.ToString()); 

在ExpandoObject上设置属性的方法也不同。以下是通过变量名称设置属性的示例。

dynamic apiVar = new ExpandoObject(); 
var propertyName = "Name"; 
apiVar[propertyName] = "Test"; 
propertyName = "Start"; 
apiVar[propertyName] = 1; 
propertyName = "Stop"; 
apiVar[propertyName] = 2; 

我总是重复使用RouteValueDictionary类。它有一个接受任何对象的构造函数,而类本身实现了IDictionary。

这是在对System.Web DLL提供

private Dictionary<string, string> GenerateQueryParameters(object queryParametersObject) 
{ 
    return new RouteValueDictionary(queryParametersObject).ToDictionary(d => d.Key, d => Convert.ToString(d.Value)); 
}