Web Api 2.2 OData V4 函数路由

Posted

技术标签:

【中文标题】Web Api 2.2 OData V4 函数路由【英文标题】:Web Api 2.2 OData V4 Function Routing 【发布时间】:2014-10-08 08:02:58 【问题描述】:

我有一个使用 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

【问题讨论】:

只是好奇,你试过了吗:something/odata/Products/MostExpensive? 是的,我尝试了任意数量的不同组合:像 odata/Products/MostExpensive、odata/Products/MostExpensive()、odata/Products/Default.MostExpensive()(当我没有明确设置命名空间) 谢谢,我也注意到没有响应类型属性[ResponseType(typeof(decimal))]。 感谢您的建议,但 ResponseType 属性似乎在此版本的 WebApi 中不可用(或者我缺少使用...)。而且,在我看到的所有示例中,这不是必需的(我在上面的 MS 示例中添加了链接)。奇怪的是我可以毫无问题地添加一个未绑定的函数,我只是无法将函数绑定到实体集。 【参考方案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

【讨论】:

我的 web.config 中有一条非常相似的行: - 如果路径属性,我看到的唯一不同。如果我把它改成你的,一切都会出现 500(内部服务器错误) 路径属性和动词看起来都很可疑。对于动词,请使用“”,对于路径,如果“/”不适合您,请尝试“”和“*/odata/”。 抱歉,我花了这么长时间才接受这个答案,但我没能花时间尝试一下。 似乎已经解决了我所有的问题......虽然我不确定为什么默认情况下它不会存在。谢谢! 这可以在不为每个请求运行所有托管模块的情况下完成(参见链接)。运行所有托管模块可能很昂贵并且可能导致错误:britishdeveloper.co.uk/2010/06/…【参考方案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>

【讨论】:

从“*”更改路径。 to "/*" 对我来说真的很有帮助。【参考方案3】:

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

config.EnableUnqualifiedNameCall(true);

您的网址将如下所示:

http://something/odata/Products/MostExpensive

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

【讨论】:

不客气!该功能在该软件包的 5.3.0 版本中不可用(这是我下载的示例解决方案使用的版本),但它在 5.7.0 中可用,所以我猜这几个月都没有以前。 我无法让任何基于web.config 的解决方案正常工作。无论如何,这更可取,因为命名空间似乎完全是多余的。 Microsoft.AspNet.OData nuget 6.1.0 中不存在此扩展方法。可以在这里找到解决方法github.com/OData/WebApi/blob/OData60/OData/test/E2ETest/…

以上是关于Web Api 2.2 OData V4 函数路由的主要内容,如果未能解决你的问题,请参考以下文章

XPO - Web API and OData V4 支持

Web API OData V4 在本地工作,但不在 IIS 上

使用 OData v4 Web API 脚手架时出错

带有 odata 和 $expand 的 Web Api 2.2

OData v4 WebAPI 响应中的项目计数

[转]OData的初步认识 OData v4 Client Code Generator