.net core 如何在IQueryCollection与任何类型之间创建映射?

.net core 如何在IQueryCollection与任何类型之间创建映射?,.net-core,azure-functions,automapper,.net Core,Azure Functions,Automapper,我有一个Azure函数,它接收IQueryCollection参数,我需要(使用automapper)转换为任何对象 从这个示例查询字符串 …我要映射到此类型: 公共类人物 { 公共int Id{get;set;} 公共字符串名称{get;set;} } 我使用如下映射: var response=wait personService.GetPerson(_mapper.Map(request.GetQueryParameterDictionary()); GetQueryParamete

我有一个Azure函数,它接收IQueryCollection参数,我需要(使用automapper)转换为任何对象

从这个示例查询字符串

…我要映射到此类型:

公共类人物
{
公共int Id{get;set;}
公共字符串名称{get;set;}
}
我使用如下映射:

var response=wait personService.GetPerson(_mapper.Map(request.GetQueryParameterDictionary());
GetQueryParameterDictionary()返回IDictionary

我测试了这张地图(但不起作用):

CreateMap();
CreateMap();
CreateMap();

您缺少的是特定类型的映射。
默认情况下,自动映射器仅尝试按属性名称映射属性

由于您正试图从特定查询参数映射到特定属性,因此需要告诉
配置文件
如何进行映射:

this.CreateMap()
.ForMember(person=>person.Id,expression=>expression.MapFrom(query=>int.Parse(query[“Id”][0]))
.ForMember(person=>person.Name,expression=>expression.MapFrom(query=>query[“Name”][0]);
但是,如果您想要创建一个通用映射器,以支持实际的任何类型,您将需要做大量的工作

您必须使用反射来检查目标的所有属性,并在查询集合中找到它们的值此外,您必须将它们从字符串转换为实际值

以下是您必须在AutoMapper
配置文件中执行的操作的开始:

CreateMap()
.ForAllMembers(表达式=>
{
//检查查询集合中是否存在该名称
string name=expression.DestinationMember.name.ToLower();
expression.premission(query=>query.ContainsKey(name));
//自动映射通常只支持属性
PropertyInfo destinationProperty=expression.DestinationMember作为PropertyInfo;
if(destinationProperty==null)
返回;
//转换不同的类型。
//对于要映射的每种类型,继续下面的模式。
如果(destinationProperty.PropertyType==typeof(字符串))
{
expression.MapFrom(query=>query[name][0]);
}
else if(destinationProperty.PropertyType==typeof(int))
{
expression.MapFrom(query=>int.Parse(query[name][0]);
}
});
结果 对于路线:
至于守则:

[FunctionName(“QueryCollectionTest”)]
公共IActionResult查询集合测试(
[HttpTrigger(AuthorizationLevel.Anonymous,“get”,Route=“test”)]HttpRequest请求)
{
Person=\u mapper.Map(请求查询);
返回新的OkResult();
}
我已绘制了以下地图:

旁注:

有了C#8,您可以使用它使上述代码变得更好,但这是另一个问题的答案。:)

最后,我创建了这样一个方法:

公共静态类HttpRequestMapper
{
公共静态T查询(IQueryCollection)
{
var instance=Activator.CreateInstance();
foreach(instance.GetType().GetProperties()中的var属性)
{
foreach(集合中的var项)
{
if(item.Key==property.Name)
{
如果(property.PropertyType==typeof(Guid)| | property.PropertyType==typeof(Guid?)
SetValue(实例,新Guid(item.Value));
如果(property.PropertyType==typeof(DateTime)| | property.PropertyType==typeof(DateTime?)
SetValue(实例,Convert.ToDateTime(item.Value));
if(property.PropertyType==typeof(string))
SetValue(实例,item.Value.ToString());
如果(property.PropertyType==typeof(int)| | property.PropertyType==typeof(int?)
SetValue(实例,int.Parse(item.Value));
如果(property.PropertyType==typeof(decimal)| | property.PropertyType==typeof(decimal?)
SetValue(实例,decimal.Parse(item.Value));
如果(property.PropertyType==typeof(long)| | property.PropertyType==typeof(long?)
SetValue(实例,long.Parse(item.Value));
如果(property.PropertyType==typeof(bool)| | property.PropertyType==typeof(bool?)
SetValue(实例,bool.Parse(item.Value));
}
}
}
返回实例;
}
}

为什么两个参数需要automapper?这只是一个示例,我有一个包含许多参数的大查询字符串,但。。。如何配置Automapper配置文件?文档中有一节解释了配置配置文件:谢谢,但我不确定这是否是合适的解决方案,因为您需要验证每种类型、空值等…好吧,是的!这正是问题所在。C#中的值类型无法从其他类型动态映射。在其他每个.Net库中都可以看到这样的示例。LINQ就是一个很好的例子。看看如何实现Sum、Min、Max和其他: