2013-11-13 2 views
2

Im создает решение WebAPI OData, которое обрабатывает объекты нетипизированных объектов, как описано в this excellent post. Как этот пост, я определяю мой EdmModel заранее, и использовать метод MapODataRoute и передать в модели использования:MapODataRoute и ODataQueryOptions

config.Routes.MapODataRoute("odata", "odata", ModelBuilder.GetEdmModel()); 

Однако, это не похоже на работу с параметром ODataQueryOptions в моих методах:

Get(ODataQueryOptions query) 
{ 
} 

Приведенная ниже ошибка: Данная модель не содержит тип 'System.Web.Http.OData.IEdmEntityObject'. Имя параметра: elementClrType

Есть ли способ получить ODataQueryOptions для работы с MapODataRoute?

ответ

3

Вы должны создать ODataQueryOptions вручную в действии вашего контроллера в нетипизированном режиме. Пример кода следующим образом,

ODataPath path = Request.GetODataPath(); 
IEdmType edmType = path.EdmType; 

IEdmType elementType = edmType.TypeKind == EdmTypeKind.Collection 
    ? (edmType as IEdmCollectionType).ElementType.Definition 
    : edmType; 

// build the typeless query options using the element type. 
ODataQueryContext queryContext = new ODataQueryContext(Request.GetEdmModel(), elementType); 
ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, Request); 
+0

Привет Raghuram, спасибо за Ваш ответ, то есть именно то, что ив делать, увидеть код в моем ответ. Он выдает ошибку с $ select и $ expand, хотя ... – stefjnl

+0

В качестве примечания, похоже, что если вы это делаете, вам также не нужно определять возвращенную коллекцию как 'IQueryable'. Я сработал с ошибками сериализации, пока не вернулся к 'IEnumerable'. –

+0

Обратите внимание, что для более поздних версий этот метод отмечен как устаревший. Используйте 'System.Web.Http.OData.Extensions.HttpRequestMessageExtensions.ODataProperties (запрос) .Path'. –

0

Ive удалось это сделать следующим образом:

ODataPath path = Request.GetODataPath(); 
IEdmType edmType = path.EdmType; 

private ODataQueryOptions GetODataQueryOptions(IEdmType edmType) 
    { 
     IEdmModel model = Models.ModelBuilder.GetEdmModel(); 
     ODataQueryContext queryContext = new ODataQueryContext(model, edmType); 
     ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, this.Request); 

     return queryOptions; 
    } 

Это работает для большинства вариантов запросов, но падает с $ выбрать и $ вставит: Тип «Collection ([Org .Microsoft.Product Nullable = False]) 'не является типом сущности. Только типы объектов поддерживают $ select и $ expand. Есть ли способ избежать этого исключения корректно, когда клиент пытается фильтровать с $ выбрать и $ расширить, или я должен просто написать что-то вроде

if (Request.RequestUri.Query.Contains("select")) { return errormessage } 

Кроме того, и что более важно, как бы один применить эти параметры запроса до EdmEntityObjectCollection, который возвращается в первом методе?

queryOptions.ApplyTo(collectionProduct.AsQueryable()); // wont work... 

(возможно, это лучшая практика для динамического построения вашей коллекции в отношении вариантов запроса в любом случае)

+1

EdmType, который вы передаете в 'ODataQueryContext', является типом элемента. Итак, если 'ODataPath.EdmType' является коллекцией, вы должны получить тип элемента и использовать его. Я уточню свой ответ, чтобы позаботиться об этом. –

+1

Кроме того, в отношении ApplyTo. Мы не поддерживаем ApplyTo в нетипизированном ODataQueryOptions, так как не существует типа CLR, а для IQueryable требуется тип CLR. Таким образом, вы должны применить ODataQueryOptions самостоятельно на своем сервере, а затем преобразовать результат в «EdmEntityObjectCollection». Это сообщение в блоге может вас немного поправить - http://blogs.msdn.com/b/webdev/archive/2013/02/25/translating-odata-queries-to-hql.aspx –

+0

спасибо за разъяснение RaghuRam! – stefjnl

Смежные вопросы