2015-01-20 4 views
4

Я пытаюсь добавить поддержку запросов OData v4 к методу на контроллере, который наследуется от ApiController, а не ODataController. Хотя у меня есть рабочая модель OData в решении, есть некоторые конечные точки, которые на самом деле не принадлежат модели, но полезность запроса будет полезна.Включить запрос OData v4 на WebApi ApiController

Я видел некоторые статьи, предлагающие мне просто вернуть IQueryable и использовать EnableQuery.

Вот мой пример код:

public class TestController : ApiController 
{ 
    [HttpGet]  
    [EnableQuery] 
    public IQueryable<TestObject> Events() 
    { 
     var result = new[] { new TestObject { Id = "1" } }.AsQueryable(); 
     return result; 
    } 
} 

public class TestObject 
{ 
    public string Id { get; set; } 
} 

Все, что я вернусь, когда вызов/Test/Событие является 406 не приемлем, то, что я столкнулся много дела с OData, что обычно означает, что я «Вернуть то, что не нравится в OData framework. Я никогда не мог получить больше информации из фреймворка (что, по большому счету, я думаю) о том, почему это ему не нравится, и только решает их в результате проб и ошибок в прошлом.

У кого-нибудь есть эта настройка, и если да, то как?

Или любые предложения по отладке ответа 406?

EDIT:

ИТАК оказалось, что преступник был так код в запуске, который регистрировал пользовательский ODataMediaTypeFormatter и в процессе убирала все остальные форматтеры.

После устранения оскорбительного кода он сработал.

Действительно, желательно, чтобы WebApi записывал где-то то, что вызвало ошибку 406, когда она выплевывает один из них.

+0

Как вы объявили маршрут? – nlips

+0

У меня нет, я только что использовал соглашения Controller/Action. Он отлично работает, когда я удаляю EnableQuery. – Mant101

+0

Изменяет ли название действия события() на Get()? – eoghank

ответ

0

Вы можете применить магию «запрос» вручную, без [EnableQuery].

  1. Создать ODataQueryContext, переходящая в вашей модели (вам нужно сохранить его в глобальном, так и сделать его доступным), и тип сущности ваш являются выполнение запроса против.
  2. Создайте HttpRequestMessage, используя Get и текущий url (Request.RequestUri.AbsoluteUri).
  3. Создайте новый ODataQueryOptions <yourEntity>, передавая в контексте и сообщение , которое вы создали.
  4. Вызов этого объекта ApplyTo с использованием вашей сущности. AsQueryable(), отливая результат как IQueryable <yourEntity>.

Дальнейшая обработка необходима и возврат. Имейте в виду, что тип возврата не обязательно должен быть IQueryable <yourEntity>, или даже основан на «yourEntity».

Вот подобная реализация, которая делает это для метода ODataController (как база ODataQueryOptions приходит бесплатно):

 public IEnumerable<Aggregate> GetOrders(ODataQueryOptions<ReportingOrder> opts, [FromUri(Name="$groupby")]string groupby, [FromUri(Name="$aggregates")]string aggregates = null) 
     { 
      var url = opts.Request.RequestUri.AbsoluteUri; 


      int? top = null; 

      if (opts.Top != null) 
      { 
       top = int.Parse(opts.Top.RawValue); 

       var topStr = string.Format("$top={0}", top.Value); 
       url = url.Replace(topStr, ""); 
       var req = new HttpRequestMessage(HttpMethod.Get, url); 

       opts = new ODataQueryOptions<ReportingOrder>(opts.Context, req); 

      } 

      var query = opts.ApplyTo(db.ReportingOrders.AsQueryable()) as IQueryable<ReportingOrder>; 

      var results = query.GroupBy(groupby, aggregates, top); 

      return results; 
     } 
Смежные вопросы