Web Api 2.2 OData V4功能路由

本文关键字:功能 路由 V4 OData Api Web | 更新日期: 2023-09-27 18:17:57

我有一个使用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暴露的元数据没有提供任何线索。是否有其他方法可以发现应该在何处(以及如何)公开此函数?

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

Web Api 2.2 OData V4功能路由

请按如下方式更改元素,如果请求URL中有点,建议这样做:

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

和if

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

被请求时,我可以得到数据:

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

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

config.EnableUnqualifiedNameCall(true);

你的URL看起来像这样:

http://something/odata/Products/MostExpensive

看到http://odata.github.io/WebApi/06-01-custom-url-parsing。可以在microsoft . asp.net . odata NuGet包中找到

那么您可以尝试添加不替换它们的部分。我的程序如下图所示,它可以工作。

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