Web API Queryable - 如何应用 AutoMapper? [英] Web API Queryable - how to apply AutoMapper?

查看:15
本文介绍了Web API Queryable - 如何应用 AutoMapper?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个像这样用 OData 可查询属性修饰的简单 WebApi 方法.

I've got a simple WebApi method like this decorated with the OData queryable attribute.

    [Queryable]
    public virtual IQueryable<PersonDto> Get()
    {
        return uow.Person().GetAll()); // Currently returns Person instead of PersonD
    }

我想要做的是在 WebAPI 将结果转换为 JSON 之前,使用 AutoMapper 将查询结果从 Person 类型转换为 PersonDto 类型.

What I want to do is transform the result of the query from type Person to type PersonDto using AutoMapper before WebAPI converts the result to JSON.

有人知道我该怎么做吗?我知道,我可以在 GetAll() 调用之后应用 Mapper.Map,然后转换回 IQueryable,但是这会导致在应用 OData 过滤器之前返回并映射整个表(不好!).

Does anybody know how I can do this? I am aware, I could apply Mapper.Map after the GetAll() call and then convert back to IQueryable, however this would result in the entire table being returned and mapped before the OData filter is applied (not good!).

看起来这个问题 ASP.NET Web API 返回可查询的 DTO? 涵盖了相同的问题(请参阅第二个回复以获得更好的答案),其中建议使用自定义 MediaTypeFormatter 在链的末尾使用 AutoMapper,但是我不知道如何根据我的示例执行此操作见过.

It would appear that this question ASP.NET Web API return queryable DTOs? covers the same issue (see second response for a better answer), where the suggestion is to use AutoMapper at the end of the chain using a custom MediaTypeFormatter, however I have no idea how to do that based on the example I have seen.

如有任何帮助,我们将不胜感激!

Any help will be gratefully received!

-- 更多信息

我已经查看了 IQueryable 的源代码,但不幸的是,我看不到任何将代码用于此目的的方法.我已经设法编写了一个似乎有效的附加过滤器,但它肯定不是很优雅.

I've looked at the source code for IQueryable, but unfortunately there I can't see any way of utilising the code for this purpose. I have managed to write an additional filter which appears to work, however it isn't certainly isn't elegant.

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);
        }
    }
}

然后我把动作装饰成

    [Queryable]
    [PersonToPersonDtoConvert]
    public IQueryable<Person> Get()
    {
        return uow.GetRepo<IRepository<Person>>().GetAll();
    }

推荐答案

有一个更好的解决方案.试试这个:

There is a better solution. Try this:

public virtual IQueryable<PersonDto> Get(ODataQueryOptions<Person> query)
{
    var people = query.ApplyTo(uow.Person().GetAll());
    return ConvertToDtos(people);
}

这将确保查询在 Person 而不是 PersonDTO 上运行.如果您希望通过属性而不是代码进行转换,您仍然需要实现与您所提供的类似的操作过滤器.

This will make sure the query runs on Person instead of PersonDTO. If you want the conversion to happen through an attribute instead of in code, you'll still want to implement an action filter similar to what you put up.

这篇关于Web API Queryable - 如何应用 AutoMapper?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆