Web Api 2.2 OData V4功能路由

时间:2014-08-14 15:31:06

标签: c# asp.net-web-api odata asp.net-web-api-routing

我有一个使用OData v4的Web Api 2.2项目。正常的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公开的元数据不提供任何线索。有没有其他方法可以发现这个函数应该暴露在哪里(以及如何)?

编辑:以下是我所遵循的Microsoft示例的链接: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/odata-actions-and-functions

3 个答案:

答案 0 :(得分:16)

请更改下面的元素,如果请求网址中有点,则建议使用此方法:

 <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 :(得分:7)

我知道这个问题不是最近的问题,但我找到了另一个对我有用的答案。如果您愿意从URL中删除命名空间,则可以使用

config.EnableUnqualifiedNameCall(true);

您的网址将如下所示:

http://something/odata/Products/MostExpensive

http://odata.github.io/WebApi/#06-01-custom-url-parsing。这可以在Microsoft.AspNet.OData NuGet包中找到。

答案 2 :(得分: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>