Web Api 2.2 OData V4 Функция Маршрутизация

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

Вот мой конфигурационный файл (прямо из примеров 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/Products/ProductService.MostExpensive()

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

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

Ответ 1

Измените элемент, как показано ниже, что рекомендуется, если в 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
}

Ответ 2

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

config.EnableUnqualifiedNameCall(true);

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

http://something/odata/Products/MostExpensive

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

Ответ 3

Затем вы можете попробовать добавить часть, не заменяя ее. Шахта выглядит ниже, и она может работать.

<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>