我有一个简单的 WebApi 方法,就像这样用 OData 可查询属性装饰。
[Queryable]
public virtual IQueryable<PersonDto> Get()
{
return uow.Person().GetAll()); // Currently returns Person instead of PersonD
}
我想要做的是在 WebAPI 将结果转换为 JSON 之前,使用 AutoMapper 将查询结果从 Person 类型转换为 PersonDto 类型。
有人知道我该怎么做吗?我知道,我可以在 GetAll() 调用之后应用 Mapper.Map,然后转换回 IQueryable,但这会导致在应用 OData 过滤器之前返回并映射整个表(不好!)。
看来这个问题ASP.NET Web API return queryable DTOs?涵盖了相同的问题(请参阅第二个响应以获得更好的答案),其中建议是使用自定义 MediaTypeFormatter 在链的末尾使用 AutoMapper,但是我不知道如何根据我看到的示例执行此操作。
如有任何帮助,我们将不胜感激!
--更多信息
我查看了 IQueryable 的源代码,但不幸的是,我看不到任何利用该代码来实现此目的的方法。我已经设法编写了一个额外的过滤器,它似乎可以工作,但它并不是很优雅。
public class PersonToPersonDtoConvertAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
{
HttpResponseMessage response = actionExecutedContext.Response;
if (response != null)
{
ObjectContent responseContent = response.Content as ObjectContent;
var query = (responseContent.Value as IQueryable<Student>).ToList();
response.Content = new ObjectContent<IEnumerable<StudentResource>>(query.ToList().Select(Mapper.Map<Person, PersonDto>), responseContent.Formatter);
}
}
}
然后我装饰了像这样的 Action
[Queryable]
[PersonToPersonDtoConvert]
public IQueryable<Person> Get()
{
return uow.GetRepo<IRepository<Person>>().GetAll();
}
最佳答案
使用 AutoMapper 的 Queryable Extensions .
首先,定义映射。
// Old AutoMapper API
// Mapper.CreateMap<Person, PersonDto>();
// Current AutoMapper API
Mapper.Initialize(cfg =>
cfg.CreateMap<Person, PersonDto>()
);
然后你可以使用这样的东西:
[EnableQuery]
public IQueryable<PersonDto> Get() {
// Old AutoMapper API
// return this.dbContext.Persons.Project().To<PersonDto>();
// New AutoMapper API
return this.dbContext.Persons.ProjectTo<PersonDto>();
}
编辑 04/2019:更新以反射(reflect)当前的 AutoMapper API。
关于asp.net - Web API Queryable - 如何应用AutoMapper?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14484692/