使用 OData QueryableAttribute 修改从 Web API 返回 ASP.NET 响应内容

本文关键字:NET ASP 响应 返回 API QueryableAttribute OData 修改 Web 使用 | 更新日期: 2023-09-27 18:36:40

这是我的问题。 我正在使用 ASP.NET Web API 2.0和QueryableAttribute来利用一些OData过滤功能。

public class VideoController : ApiController
{
    [HttpGet]
    [Route("activevideos")]
    [Queryable]
    public IEnumerable<Video> GetActiveVideos(ODataQueryOptions<Video> options)
    {
        return new GetvContext().Videos.Where(c => c.IsActive);
    }        
}

现在,我有一个类,我一直用它来修改响应对象和包含的实体。 在我开始使用 QueryableAttribute 之前,这工作正常。 在此之前,我从以前的方法返回一个列表,而不是 IEnumerable。

public class TestMessageProcessHandler : MessageProcessingHandler
{
    protected override HttpResponseMessage ProcessResponse(
        HttpResponseMessage response, CancellationToken cancellationToken)
    {
        var content = ((ObjectContent)(response.Content)).Value;
        // Do something here with the content.  This used to be a List<Video> 
        // but now the object it is of type: 
        // System.Data.Entity.Infrastructure.DbQuery<System.Web.Http.OData.Query.Expressions.SelectExpandBinder.SelectSome<Content.Api.Video>>
    }
}

我需要能够从中获取实体,但我不确定如何从类型中获取:

System.Data.Entity.Infrastructure.DbQuery<System.Web.Http.OData.Query.Expressions.SelectExpandBinder.SelectSome<Content.Api.Video>>类似于List<Video>的内容,以便我可以修改Video对象。

使用 OData QueryableAttribute 修改从 Web API 返回 ASP.NET 响应内容

删除 [Queryable] 属性并自行管理数据的查询 - 如下所示:

public class VideoController : ApiController
{
    [HttpGet]
    [Route("activevideos")]
    public IList<Video> GetActiveVideos(ODataQueryOptions<Video> options)
    {
        var s = new ODataQuerySettings() { PageSize = 1 };
        var result = options.ApplyTo(
            new GetvContext().Videos.Where(c => c.IsActive), s)
            .ToList();
        return result;
    }        
}

你不能只做一个 ToList() - DbQuery 实现了 IQueryable...

例如

var content = ((ObjectContent)(response.Content)).Value;
var queryable = content as IQueryable<Video>;
var list = queryable.ToList();

您很可能遇到此问题,因为您指定了 OData 查询应选择哪些字段(例如,$select=Nr,Date )。如果不这样做,则在应用查询选项后,OData 不会返回SelectSome对象,它将返回您正在查询的相同对象,在您的情况下Video 。因此,您可以在将这些对象返回到客户端之前轻松地在服务器端修改它们。

如果您需要从不需要的对象中排除Video属性,您可以使用 DTO 代替Video对象而不是$select查询选项,并在此 DTO 中仅包含您需要的字段。

是的,这是一种解决方法,希望在此库的未来版本中会有更好的方法来处理服务器端逻辑