本文转自: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的更多相关文章

  1. node-odata: ASP.NET WEB API OData的替代品

    什么是 OData 协议? OData, 相信身为 .NET 程序员应该不为陌生, 尤其是它的实现: ASP.NET WEB API OData. 对于 OData, 官网上对其的定义是 OData ...

  2. [转]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 ...

  3. 如何使用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; ...

  4. [转]ASP.NET web API 2 OData enhancements

    本文转自:https://www.pluralsight.com/blog/tutorials/asp-net-web-api-2-odata-enhancements Along with the ...

  5. Asp.Net Web Api 与 Andriod 接口对接开发经验,给小伙伴分享一下!

    最近一直急着在负责弄Asp.Net Web Api 与 Andriod 接口开发的对接工作! 刚听说要用Asp.Net Web Api去跟 Andriod 那端做接口对接工作,自己也是第一次接触Web ...

  6. Asp.Net Web Api 与 Andriod 接口对接开发

    Asp.Net Web Api 与 Andriod 接口对接开发经验,给小伙伴分享一下!   最近一直急着在负责弄Asp.Net Web Api 与 Andriod 接口开发的对接工作! 刚听说要用A ...

  7. [转]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 ...

  8. 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 ...

  9. [转]ASP.NET Web API对OData的支持

    http://www.cnblogs.com/shanyou/archive/2013/06/11/3131583.html 在SOA的世界中,最重要的一个概念就是契约(contract).在云计算的 ...

随机推荐

  1. C# autofac的一些使用

    这次项目需要用autofac动态注册插件dll,插件修改或扩展后,在不重新编译的情况下能加载新的插件. 于是我们用autofac从配置文件注册.注册的文件固定named.这样不管插件怎么变,我们Res ...

  2. 跨域处理之Jsonp

    一.认识Jsonp JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式 ...

  3. change和onChange

    change是jquery上的绑定事件,可用于下拉框动态关联数据: $(function(){ $("#id").change(function(e){ alert($(this) ...

  4. phpStorm配置SVN与FTP数据传输

    公司php开发时候,需要搭建环境,自己捋了下思路,公司代码放在SVN服务器上,需要在本机安装TortoiseSVN软件,将代码下载到本机,在本机上调试程序,修改代码,修改的代码再上传到SVN.之后通过 ...

  5. zookeeper 高可用集群搭建

    前言 记录Zookeeper集群搭建的过程! 什么是 Zookeeper ? ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hado ...

  6. java连接hbase时出现....is accessible from more than one module:

    今天在用java程序连接hbase时,出现错误,The package org.apache.hadoop.hbase is accessible from more than one module: ...

  7. PHP中引入文件的四种方式详解

    四种语句 PHP中有四个加载文件的语句:include.require.include_once.require_once. 基本语法 require:require函数一般放在PHP脚本的最前面,P ...

  8. 2. C++11 构造函数相关

    1. 继承构造函数 派生类如果要使用基类的成员函数,可以通过using声明来完成. #include <iostream> using namespace std; class Base ...

  9. 安装vuecli和使用elememtUi

    首先需要下载node.js,这里只需要一步步的安装就可以,无需要做其他的事, 第二步:安装vue 第三步:安装脚手架 第四步: 由于国内访问npm比较慢,可以按照cnpm npm install -g ...

  10. postman小结

    1.get和post请求,get有限制2k,post没有限制post安全 在选择的时候别把get post选错然后,run 2.data 选成txt文件  utf-8 ip ip,result12.1 ...