使用 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
对象。
删除 [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 中仅包含您需要的字段。
是的,这是一种解决方法,希望在此库的未来版本中会有更好的方法来处理服务器端逻辑