1

我正在使用 WebApi v5 和 OData v4。

我有一个从 ApiController 扩展的控制器,它具有一种轮询存储库以获取简单类别列表的方法。

public class ITSRController : ApiController
{
    private IITSRRepository repository;

    public ITSRController(IITSRRepository itsrRepository)
    {
        repository = itsrRepository;
    }

    [Route("v1/request/categories")]
    [HttpGet]
    public IQueryable<Category> Categories()
    {
        return repository.Categories.AsQueryable();
    }

Category 类是一个简单的存储库实体类:

public class Category
{
    public int Id { get; set; }
    public string CategoryName { get; set; }
}

我的 WebApiConfig 中有以下代码:

public static void Register(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();
    config.AddODataQueryFilter();

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "itsrapi/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}

没有任何额外的代码,我得到了 GET 请求的预期结果,例如:

v1/request/categories/?$orderby=CategoryName
v1/request/categories/?$filter=CategoryName eq 'Cat1' or CategoryName eq 'Cat2'
v1/request/categories/?$top=4&$orderby=Id&$skip=4

当我发出以下 GET 请求时:v1/request/categories/?$select=CategoryName

我得到以下异常:

“System.Linq.EnumerableQuery 1[System.Web.Http.OData.Query.Expressions.SelectExpandBinder+SelectSome1[SWF.ITSR.Domain.Entities.Category]]”类型的对象无法转换为“System.Collections.Generic.IEnumerable`1[SWF.ITSR.Domain.Entities.Category]”类型.

经过一番研究,我在控制器中更改了 Categories 方法:

[Route("v1/request/categories")]
[HttpGet]
[EnableQuery]
public IQueryable<Category> Categories(ODataQueryOptions options)
{
    if (options.SelectExpand != null)
    {
        Request.ODataProperties().SelectExpandClause = options.SelectExpand.SelectExpandClause;
    }

    return repository.Categories.AsQueryable();
}

当我在此更改后调用 $select 时,我得到与上述相同的错误。

我尝试将方法修改为以下内容:

public IEnumerable<Category> Categories(ODataQueryOptions options)
{
    ...
    return repository.Categories.ToList();
}

我在调用 $select 时遇到了一个稍微不同的异常

无法将“System.Linq.EnumerableQuery 1[System.Web.Http.OData.Query.Expressions.SelectExpandBinder+SelectSome1[SWF.ITSR.Domain.Entities.Category]]”类型的对象转换为“System.Collections.Generic.IEnumerable`1[SWF.ITSR.Domain.Entities.Category]” .

这可能在语义上与第一个错误相同(可能在其他地方失败)

我花了很多时间研究如何将 $select(和 $expand)功能添加到我的 WebApi 控制器,但无济于事。我已经尝试了无数张贴的建议,但仍然没有答案。我将不胜感激任何帮助。

谢谢,

4

2 回答 2

0

您是否有理由同时使用 Web API 和 Web API OData?如果没有,我建议你 Controller 直接从 ODataController 继承。然后你不需要指定任何特定的东西来使 $select 工作。一个例子是https://github.com/OData/ODataSamples/tree/master/SampleService

于 2014-09-08T05:38:01.220 回答
0

如果出于某种原因,您打算使用 ApiController,则可以使用我在此响应中描述的技术。但是推荐的方法是使用QianLi提到的ODataController

于 2015-06-23T16:32:05.327 回答