带有字符串键的 ASP.Net OData [英] ASP.Net OData with string keys
问题描述
我正在尝试使用 ASP.Net OData v4(例如 ODataController)来允许访问键是字符串的情况.95% 的示例使用整数作为键,我发现的几篇讨论使用字符串作为键的步骤的帖子对我不起作用.
I am trying to use ASP.Net OData v4 (e.g. ODataController) to allow access where the key is a string. 95% of the examples out there use an integer as a key and the couple of posts I've found that discuss the steps to use a string as the key aren't working for me.
在所有情况下,我都尝试使用以下 URL 访问我的资源:
In all cases, I am trying to access my resource with the following URL:
/api/ContactTypes('Agency')
/api/ContactTypes('Agency')
乐观地,我一开始只是将键的类型从 int 更改为 key:
Optimistically, I started with just changing the type of the key from int to 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).
But I get a 404 response. Changing the URL to an integer, /api/ContactTypes(1) does "work" in that it routes to the correct method and that the key is a string type, but obviously, that doesn't help me. This is the scenario described in this post: How to get ASP.Net Web API and OData to bind a string value as a key? except that that post implies that accessing the URL the way I am should work (and also is for OData v3).
进一步搜索后,我找到了这篇文章:https://blogs.msdn.microsoft.com/davidhardin/2014/12/17/web-api-odata-v4-lessons-learned/ 基本上说你必须使用显式路由装饰 Get 方法:
After further searching, I found this article: https://blogs.msdn.microsoft.com/davidhardin/2014/12/17/web-api-odata-v4-lessons-learned/ which basically says that you have to decorate the Get method with an explicit routing:
[ODataRoute("({key})")]
public SingleResult<ContactType> Get([FromODataUri] string key)
但是,如果我单独执行此操作,我会在控制器ContactTypes"中的操作Get"上得到路径模板({key})"不是有效的 OData 路径模板.请求 URL 中遇到空段.请确保指定了有效的请求 URL."
If I do that alone, though, I get "The path template '({key})' on the action 'Get' in controller 'ContactTypes' is not a valid OData path template. Empty segment encountered in request URL. Please make sure that a valid request URL is specified."
这篇文章中的评论(https://damienbod.com/2014/06/16/web-api-and-odata-v4-crud-and-actions-part-3/) 建议我需要用 ODataRoutePrefix 装饰控制器:
The comments in this post (https://damienbod.com/2014/06/16/web-api-and-odata-v4-crud-and-actions-part-3/) suggest that I need to decorate the Controller with an ODataRoutePrefix:
[ODataRoutePrefix("ContactTypes")]
public class ContactTypesController : ODataController
这似乎违反直觉,因为我没有任何 ASP.Net 应该令人困惑的东西.我的控制器名称已经遵循惯例,而且我没有可能会混淆它的 Web API 控制器.
That seems counter-intuitive since I do not have anything ASP.Net should be confusing. My controller name is already following convention and I have no Web API controllers that could be confusing it.
无论如何,它似乎确实修复"了问题,因为错误消失了,但我又回到了第一个地方(例如,URL 中只能传递整数值).
Regardless, it does seem to "fix" the issue in that the error goes away, but then I am right back at square one (e.g. only integer values can be passed in the 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:
Full 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()
);
}
推荐答案
1.如果在你的EdmModel
中,string属性是key,则不需要ODataRoute,例如:
1.If in your EdmModel
, the string property is key, then no ODataRoute is need, for example:
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
}
ConventionModelBuilder 将使用名为Id"的属性作为键,或者您应该指定它是一个键,例如:
ConventionModelBuilder will use property named "Id" as the key, or you should specify it's a key like:
public class Product
{
[Key]
public string StringKey { get; set; }
public string Name { get; set; }
public double Price { get; set; }
}
然后像 localhost\api\Products('test')
这样的调用应该转到
Then the call like localhost\api\Products('test')
should just go to
public SingleResult<Product> GetProduct([FromODataUri]string key)
2.如果你已经有一个int作为key,但是你想使用string作为另一个key,那么你应该试试这个功能:http://odata.github.io/WebApi/#04-17-Alternate-Key ,你可以这样调用:localhost\api\Products(StringKey='test')
2.If you already have a int as a key, but you want use string as another key, then you should try this feature: http://odata.github.io/WebApi/#04-17-Alternate-Key , and you can call like:
localhost\api\Products(StringKey='test')
这篇关于带有字符串键的 ASP.Net OData的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!