2014-08-14 7 views
12

У меня есть проект Web Api 2.2, работающий с OData v4. Обычная конфигурация EntitySet работает по желанию со всеми глаголами http. Там, где у меня проблема, вы пытаетесь открыть пользовательскую функцию. Я начал пытаться сделать что-то отличное от стандартных примеров, но я полностью поддержал это, пытаясь заставить работать базовый пример.Web Api 2.2 OData V4 Функция Маршрутизация

Вот мой запуск конфигурации (прямо из примеров MS):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web.Http; 
using System.Web.OData.Builder; 
using System.Web.OData.Extensions; 

namespace Test.Service 
{ 
    public static class WebApiConfig 
    { 
     public static void Register(HttpConfiguration config) 
     { 

      // other entitysets that don't have functions 

      builder.EntitySet<Product>("Products"); 
      builder.Namespace = "ProductService"; 
      builder.EntityType<Product>().Collection 
       .Function("MostExpensive") 
       .Returns<double>(); 

      config.MapODataServiceRoute(
       "odataroute" 
       , "odata" 
       , builder.GetEdmModel()       
       ); 
     } 
    } 
} 

А вот мой контроллер:

using System.Data.Entity; 
using System.Data.Entity.Infrastructure; 
using System.Linq; 
using System.Net; 
using System.Threading.Tasks; 
using System.Web.Http; 
using System.Web.OData; 

namespace Test.Service.Controllers 
{ 
    public class ProductsController : ODataController 
    { 
     private EntityContext db = new EntityContext(); 

     [EnableQuery] 
     public IQueryable<Product> GetProducts() 
     { 
      return db.Products; 
     } 

     [HttpGet] 
     public IHttpActionResult MostExpensive() 
     { 
      double test = 10.3; 
      return Ok(test); 
     } 
    } 
} 

Регулярное GET, работает отлично:

http://something/odata/Products 

Однако следующее всегда дает мне 404:

Я пробовал любое количество разных вещей с пространством имен и т. Д. Итак, он не работает, как и все примеры, но я в недоумении, как копать глубже, чтобы выяснить что происходит не так. Метаданные, выставленные http://something/odata, не дают никаких подсказок. Есть ли другой способ узнать, где (и как) эта функция должна быть раскрыта?

EDIT: Вот ссылка на Microsoft примера я следующее: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/odata-actions-and-functions

+0

Просто интересно, вы пробовали: http: // something/odata/Продукты/MostOpensive? –

+0

Да, я пробовал любое количество различных комбинаций: например odata/Продукты/MostExpensive, odata/Продукты/MostExpensive(), odata/Продукты/Default.MostExpensive() (последний, когда я не задал явно пространство имен) –

+0

Спасибо, я также заметил, что нет атрибута типа ответа [ResponseType (typeof (decimal))]. –

ответ

16

Пожалуйста, измените элемент, как показано ниже, что является рекомендуемым способом, если есть точка в запросе URL:

<system.webServer> 
    <modules runAllManagedModulesForAllRequests="true" /> 
</system.webServer> 

и если

http://something/odata/Products/ProductService.MostExpensive() 

испрашивается, я могу получить данные:

{ 
@odata.context: "http://localhost:14853/odata/$metadata#Edm.Double", 
value: 3 
} 
+1

У меня очень похожая строка в моем web.config: - единственное, что я вижу с вашим, если атрибут path. Если я изменю его на ваш, все будет иметь 500 (внутренняя ошибка сервера) –

+0

Оба атрибута пути и глагола выглядят подозрительными. Для глагола используйте «*» и для пути, если «/ *» не работает для вас, попробуйте «*» и «*/odata/*». –

+0

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

2

Тогда вы можете попробовать добавить деталь, не заменяя их. Мой выглядит как внизу, и он может работать.

<handlers> 
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> 
    <remove name="OPTIONSVerbHandler" /> 
    <remove name="TRACEVerbHandler" /> 
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> 
    <clear/> 
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="/*" 
     verb="*" type="System.Web.Handlers.TransferRequestHandler" 
     preCondition="integratedMode,runtimeVersionv4.0" /> 
</handlers> 
+1

Изменение пути из "\ *." to "/ \ *" действительно помогает в моем случае. – VAV

7

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

config.EnableUnqualifiedNameCall(true); 

Ваш URL будет выглядеть следующим образом:

http://something/odata/Products/MostExpensive 

См http://odata.github.io/WebApi/#06-01-custom-url-parsing. Это доступно в пакете Microsoft.AspNet.OData NuGet.

+1

спасибо - это именно то, что я хотел в то время! –

+0

Вы очень желанны! Функция недоступна в версии 5.3.0 этого пакета (которая является версией, используемой образцом, которую я загрузил), но она доступна в 5.7.0, поэтому я предполагаю, что это было не во всех этих месяцах тому назад. –

+1

Я не мог заставить работать какое-либо решение на основе 'web.config'. Это было предпочтительнее, так как пространство имен кажется совершенно лишним. –

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