2014-09-05 4 views
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(); 
    } 

КАТЕГОРИЯ класс является простой класс хранилище Entity:

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/запрос/категории/$ выберите = CategoryName

я получаю следующее исключение:

объект типа «System.Linq.EnumerableQuery 1[System.Web.Http.OData.Query.Expressions.SelectExpandBinder+SelectSome 1 [ SWF.ITSR.Domain.Entities.Category]] ' не могут быть преобразованы в тип' System.Collections.Generic.IEnumerable`1 [SWF.ITSR.Domain.Entities.Category] '.

После некоторых исследований я изменил мой метод Категории в моем контроллере:

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

Когда я называю $ выбрать после этого изменения я получаю ту же ошибку, что и выше.

Я попытался модифицировать метод к следующему:

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

и я получаю немного другое исключение при вызове $ выберите

Невозможно привести объект типа «System.Linq .EnumerableQuery 1[System.Web.Http.OData.Query.Expressions.SelectExpandBinder+SelectSome 1 [SWF.ITSR.Domain.Entities.Category]] ' , чтобы напечатать' System.Collections.Generic.IEnumerable`1 [SWF.ITSR.Domain.Entities.Category] '.

, которые могут быть семантически же, как и первая ошибка (возможно, неудачу где-то еще)

Я потратил довольно много времени, исследования, как не добавить $ выбора (и $ расширить) функциональность моего контроллера WebAPI к не помогло. Я пробовал бесчисленные опубликованные предложения, и все же ответ ускользает от меня. Буду признателен за любую помощь.

Спасибо,

Кен

ответ

0

Есть ли причина для того, чтобы использовать как Web API и Web API OData? Если нет, я предлагаю вам наследовать Controller непосредственно из ODataController. Тогда вы не укажете ничего особенного, чтобы сделать операцию $ select.Примером может служить https://github.com/OData/ODataSamples/tree/master/SampleService

+0

Я пробовал это, однако, когда я наследую ODataController, я не получаю ответа от запроса GET. Я изучил этот вопрос, но до сих пор у меня не было успеха в устранении неполадок, почему это происходит. Я посмотрю вашу ссылку и попытаюсь устранить ее. Благодарю. – sloaniebaloney

+0

И, возможно, меньший пример фокусировки на $ select и $ expand может спасти ваше время устранения неполадок. http://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/SelectExpandDollarValueSample/ – QianLi

+0

Мне удалось получить эту работу, используя это. Благодаря! – sloaniebaloney

0

Если по какой-либо причине вы собираетесь использовать ApiController, вы можете использовать технику, описанную в this response. Но рекомендуемым способом является использование ODataController, как было упомянуто в QianLi