[转]Support Composite Key in ASP.NET Web API OData
本文转自:https://code.msdn.microsoft.com/Support-Composite-Key-in-d1d53161
he default EntitySetController doesn't support composite keys. So if you have composite key models, you need some additional work. Here is an example about how to do that.
The model is simple:
public class Person
{
[Key]
public string FirstName { get; set; }
[Key]
public string LastName { get; set; }
public int Age { get; set; }
}
The odata url for this model will look like:
GET http://localhost:33051/People(FirstName='Kate',LastName='Jones') HTTP/1.1
And we want to have strong typed parameters in web api actions to this URL.
public Person Get([FromODataUri] string firstName, [FromODataUri] string lastName)
Note that the FromODataUri model binder attribute is used to parse from odata uri representation to clr type. In odata, string value is "'xxx'" and we want it to be "xxx".
In order to make the route to work, you can add a custom routing convention to parse the key path. Here is a sample implementation:
public class CompositeKeyRoutingConvention : EntityRoutingConvention
{
public override string SelectAction(System.Web.Http.OData.Routing.ODataPath odataPath, System.Web.Http.Controllers.HttpControllerContext controllerContext, ILookup<string, System.Web.Http.Controllers.HttpActionDescriptor> actionMap)
{
var action = base.SelectAction(odataPath, controllerContext, actionMap);
if (action != null)
{
var routeValues = controllerContext.RouteData.Values;
if (routeValues.ContainsKey(ODataRouteConstants.Key))
{
var keyRaw = routeValues[ODataRouteConstants.Key] as string;
IEnumerable<string> compoundKeyPairs = keyRaw.Split(',');
if (compoundKeyPairs == null || compoundKeyPairs.Count() == 0)
{
return action;
}
foreach (var compoundKeyPair in compoundKeyPairs)
{
string[] pair = compoundKeyPair.Split('=');
if (pair == null || pair.Length != 2)
{
continue;
}
var keyName = pair[0].Trim();
var keyValue = pair[1].Trim();
routeValues.Add(keyName, keyValue);
}
}
}
return action;
}
}
The convention is inherited from EntityRoutingConvention, which is the default convetion to handle entity key. By calling base.SelectAction, it will add the full key path into routeValues. The new convention will check if it contains "," and seperate it into multiple keys and set each of them into routeValues. So when web api select actions, it will use those values to determine which action to choose. If there is no "," found, it behaves same as base convetion.
To register the convetion, you need to set it when mapping odata route:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.EnableQuerySupport();
var mb = new ODataConventionModelBuilder(config);
mb.EntitySet<Person>("People");
var conventions = ODataRoutingConventions.CreateDefault();
conventions.Insert(0, new CompositeKeyRoutingConvention());
config.Routes.MapODataRoute(
routeName: "OData",
routePrefix: null,
model: mb.GetEdmModel(),
pathHandler: new DefaultODataPathHandler(),
routingConventions: conventions);
}
}
Register the route at the postion 0 is to make it be executed before other default routing convetions. So the default EntityRoutingConvetion won't be executed before it. After that, you should be able to get routing work.
Then, how to build url for composite keys?
You don't need to do that for odata links include edit link and self link when using ODataConventionModelBuilder. It will automatically identify composite keys and build the uri for you.
However, you need to build the link for location header. Here is a sample code from PeopleController.cs to handle post request:
public HttpResponseMessage PostPerson(Person person)
{
if (ModelState.IsValid)
{
_repo.UpdateOrAdd(person);
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, person);
string key = string.Format(
"{0}={1},{2}={3}",
"FirstName", ODataUriUtils.ConvertToUriLiteral(person.FirstName, Microsoft.Data.OData.ODataVersion.V3),
"LastName", ODataUriUtils.ConvertToUriLiteral(person.LastName, Microsoft.Data.OData.ODataVersion.V3));
response.Headers.Location = new Uri(Url.ODataLink(
new EntitySetPathSegment("People"),
new KeyValuePathSegment(key)));
return response;
}
else
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
Hope it helps.
[转]Support Composite Key in ASP.NET Web API OData的更多相关文章
- node-odata: ASP.NET WEB API OData的替代品
什么是 OData 协议? OData, 相信身为 .NET 程序员应该不为陌生, 尤其是它的实现: ASP.NET WEB API OData. 对于 OData, 官网上对其的定义是 OData ...
- [转]Getting started with ASP.NET Web API OData in 3 simple steps
本文转自:https://blogs.msdn.microsoft.com/webdev/2013/01/29/getting-started-with-asp-net-web-api-odata-i ...
- 如何使用ASP.NET Web API OData在Oracle中使用Entity Framework 6.x Code-First方式开发 OData V4 Service
环境: Visual Studio 2013 + .Net Framework 4.5.2 1.新建项目 2.安装OData,ODP.NET 安装的包: 下面是部分代码: using System; ...
- [转]ASP.NET web API 2 OData enhancements
本文转自:https://www.pluralsight.com/blog/tutorials/asp-net-web-api-2-odata-enhancements Along with the ...
- Asp.Net Web Api 与 Andriod 接口对接开发经验,给小伙伴分享一下!
最近一直急着在负责弄Asp.Net Web Api 与 Andriod 接口开发的对接工作! 刚听说要用Asp.Net Web Api去跟 Andriod 那端做接口对接工作,自己也是第一次接触Web ...
- Asp.Net Web Api 与 Andriod 接口对接开发
Asp.Net Web Api 与 Andriod 接口对接开发经验,给小伙伴分享一下! 最近一直急着在负责弄Asp.Net Web Api 与 Andriod 接口开发的对接工作! 刚听说要用A ...
- [转]Supporting OData Query Options in ASP.NET Web API 2
本文转自:https://docs.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/suppor ...
- Asp.Net Web API 2第十七课——Creating an OData Endpoint in ASP.NET Web API 2(OData终结点)
前言 很久没更新博客了,加上刚过年,现在准备重新开战,继续自己的学习之路.本文已同步到Web API2系列文章中http://www.cnblogs.com/aehyok/p/3446289.html ...
- [转]ASP.NET Web API对OData的支持
http://www.cnblogs.com/shanyou/archive/2013/06/11/3131583.html 在SOA的世界中,最重要的一个概念就是契约(contract).在云计算的 ...
随机推荐
- docker-compose 部署 Redis
信息: Docker版本($ docker --version):Docker版本18.06.1-ce,版本e68fc7a 系统信息($ cat /etc/centos-release):CentOS ...
- Linq的Join == 两个foreach
因为实在太懒了,很久没动笔,今天强迫自己写一个小短篇. 之前讨论过用SelectMany代替两重的foreach循环.今天我们看一下Join和foreach的关系. 首先是Join的定义 public ...
- sharepoint database 操作
select *from [dbo].[AllLists] where tp_Title='Pages' and tp_WebId='90511126-E1FE-4E4C-8DDF-74DFC89E8 ...
- 【cocos2d-x 手游研发小技巧(3)Android界面分辨率适配方案】
先感叹一下吧~~android的各种分辨率各种适配虐我千百遍,每次新项目我依旧待它如初恋···· 每家公司都有自己项目工程适配的方案,这种东西就是没有最好,只有最适合!!! 这次新项目专项针对andr ...
- 修改 nginx 默认端口
修改 nginx 默认端口 nginx 解压目录下的 conf 目录下的 nginx.conf 修改对应端口
- GO学习笔记 - 数据类型推导
官方教程:https://tour.go-zh.org/basics/14 在定义一个变量却并不显式指定其类型时(使用 := 语法或者 var = 表达式语法), 变量的类型由(等号)右侧的值推导得出 ...
- 【12c OCP】最新CUUG OCP-071考试题库(50题)
50.(11-15)choose two Examine the structure of the MARKS table: Which two statements would execute su ...
- JavaScript多个音频audio标签,点击其中一个播放时,其他的停止播放
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Java网络编程以及简单的聊天程序
网络编程技术是互联网技术中的主流编程技术之一,懂的一些基本的操作是非常必要的.这章主要讲解网络编程,UDP和Socket编程,以及使用Socket做一个简单的聊天软件. 全部代码下载:链接 1.网络编 ...
- python全栈开发_day17_时间,系统模板和序列化
一:时间模板 1)time 常用功能: time.sleep() time.time() time.strftime() import time print(time.strftime("% ...