【发布时间】:2016-08-18 10:17:26
【问题描述】:
我正在尝试使用 ASP.Net OData v4(例如 ODataController)来允许访问密钥是字符串的地方。 95% 的示例使用整数作为键,而我发现讨论使用字符串作为键的步骤的几篇文章对我不起作用。
在所有情况下,我都在尝试使用以下 URL 访问我的资源:
/api/ContactTypes('Agency')
乐观地说,我一开始只是将键的类型从 int 更改为 key:
public SingleResult<ContactType> Get([FromODataUri] string key)
但我收到了 404 响应。将 URL 更改为整数,/api/ContactTypes(1) 确实“起作用”,因为它路由到正确的方法并且键是字符串类型,但显然,这对我没有帮助。这是这篇文章中描述的场景:How to get ASP.Net Web API and OData to bind a string value as a key?,除了那篇文章暗示以我应该工作的方式访问 URL(也适用于 OData v3)。
经过进一步搜索,我找到了这篇文章:https://blogs.msdn.microsoft.com/davidhardin/2014/12/17/web-api-odata-v4-lessons-learned/,它基本上说你必须用显式路由装饰Get方法:
[ODataRoute("({key})")]
public SingleResult<ContactType> Get([FromODataUri] string key)
但是,如果我单独执行此操作,我会在控制器“ContactTypes”中的“Get”操作中收到“路径模板 '({key})' 不是有效的 OData 路径模板。请求 URL 中遇到空段。请确保指定了有效的请求 URL。”
这篇文章 (https://damienbod.com/2014/06/16/web-api-and-odata-v4-crud-and-actions-part-3/) 中的 cmets 建议我需要用 ODataRoutePrefix 装饰 Controller:
[ODataRoutePrefix("ContactTypes")]
public class ContactTypesController : ODataController
这似乎违反直觉,因为我没有任何 ASP.Net 应该令人困惑的东西。我的控制器名称已经遵循约定,并且我没有可能会混淆它的 Web API 控制器。
无论如何,它似乎确实“解决”了错误消失的问题,但我又回到了第一格(例如,只能在 URL 中传递整数值)。
我错过了什么?
完整的控制器代码:
[Authorize]
[ODataRoutePrefix("ContactTypes")]
public class ContactTypesController : ODataController
{
PolicyContext _Db;
public ContactTypesController(PolicyContext db)
{
if (db == null)
throw new ArgumentNullException("db");
this._Db = db;
}
public ContactTypesController() : this(new PolicyContext())
{
}
protected override void Dispose(bool disposing)
{
_Db.Dispose();
base.Dispose(disposing);
}
[EnableQuery]
[ODataRoute()]
public IQueryable<ContactType> Get(ODataQueryOptions options)
{
return _Db.ContactType;
}
[EnableQuery]
[ODataRoute("({key})")]
public SingleResult<ContactType> Get([FromODataUri] string key)
{
IQueryable<ContactType> result = _Db.ContactType.Where(p => p.ContactTypeKey == key);
return SingleResult.Create(result);
}
完整的 WebApiConfig:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
builder.EntitySet<ContactType>("ContactTypes");
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "api",
model: builder.GetEdmModel()
);
}
【问题讨论】: