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/”。 抱歉,我花了这么长时间才接受这个答案,但我没能花时间尝试一下。然后您可以尝试添加不替换它们的部分。我的如下所示,它可以工作。
<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 函数路由的主要内容,如果未能解决你的问题,请参考以下文章
Web API OData V4 在本地工作,但不在 IIS 上