WebAPI 2 OData - '〜/ entityset / key / $ links / navigation'没有路由约定

时间:2014-03-16 01:15:46

标签: c# asp.net web-services wcf asp.net-web-api

我对OData和WebAPI很新.2。提前抱歉。

我的目标是使用具有WcfService对象和WcfClient对象的OData服务,并通过list属性将WcfClientWcfService相关联{ {1}}。 (例如。Clients但使用OData服务)

我有一个包含service.Clients.Add(client)WcfServiceWcfClient类的EF代码第一个数据库。并且,使用Microsoft.AspNet.WebApi.OData 5.1.1进行OData Web服务设置。连接所有内容的代码都是使用VS2013中的向导设置的。 OData端点的$元数据如下所示(SoaApplication):

http://soa.local.xxx/odata/$metadata

<edmx:Edmx xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" Version="1.0"> <edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="3.0" m:MaxDataServiceVersion="3.0"> <Schema xmlns="http://schemas.microsoft.com/ado/2009/11/edm" Namespace="xxx"> <EntityType Name="SoaApplication"> <Key> <PropertyRef Name="ApplicationId"/> </Key> <Property Name="ApplicationId" Type="Edm.Int32" Nullable="false"/> <Property Name="ComputerName" Type="Edm.String"/> <Property Name="ConfigLocation" Type="Edm.String"/> </EntityType> <EntityType Name="WcfClient"> <Key> <PropertyRef Name="ClientId"/> </Key> <Property Name="ClientId" Type="Edm.Int32" Nullable="false"/> <Property Name="ApplicationId" Type="Edm.Int32" Nullable="false"/> <Property Name="Address" Type="Edm.String"/> <Property Name="Binding" Type="Edm.String"/> <Property Name="BindingConfiguration" Type="Edm.String"/> <Property Name="Contract" Type="Edm.String"/> <NavigationProperty Name="Application" Relationship="xxx.xxx_WcfClient_Application_xxx_SoaApplication_ApplicationPartner" ToRole="Application" FromRole="ApplicationPartner"/> </EntityType> <EntityType Name="WcfService"> <Key> <PropertyRef Name="ServiceId"/> </Key> <Property Name="ServiceId" Type="Edm.Int32" Nullable="false"/> <Property Name="ApplicationId" Type="Edm.Int32" Nullable="false"/> <Property Name="AddressNoScheme" Type="Edm.String"/> <Property Name="AddressForMatching" Type="Edm.String"/> <Property Name="Binding" Type="Edm.String"/> <Property Name="BindingConfiguration" Type="Edm.String"/> <Property Name="Contract" Type="Edm.String"/> <NavigationProperty Name="Application" Relationship="xxx.xxx_WcfService_Application_xxx_SoaApplication_ApplicationPartner" ToRole="Application" FromRole="ApplicationPartner"/> <NavigationProperty Name="Clients" Relationship="xxx.xxx_WcfService_Clients_xxx_WcfClient_ClientsPartner" ToRole="Clients" FromRole="ClientsPartner"/> </EntityType> <Association Name="xxx_WcfClient_Application_xxx_SoaApplication_ApplicationPartner"> <End Type="xxx.SoaApplication" Role="Application" Multiplicity="0..1"/> <End Type="xxx.WcfClient" Role="ApplicationPartner" Multiplicity="0..1"/> </Association> <Association Name="xxx_WcfService_Application_xxx_SoaApplication_ApplicationPartner"> <End Type="xxx.SoaApplication" Role="Application" Multiplicity="0..1"/> <End Type="xxx.WcfService" Role="ApplicationPartner" Multiplicity="0..1"/> </Association> <Association Name="xxx_WcfService_Clients_xxx_WcfClient_ClientsPartner"> <End Type="xxx.WcfClient" Role="Clients" Multiplicity="*"/> <End Type="xxx.WcfService" Role="ClientsPartner" Multiplicity="0..1"/> </Association> </Schema> <Schema xmlns="http://schemas.microsoft.com/ado/2009/11/edm" Namespace="Default"> <EntityContainer Name="Container" m:IsDefaultEntityContainer="true"> <EntitySet Name="SoaApplication" EntityType="xxx.SoaApplication"/> <EntitySet Name="WcfClient" EntityType="xxx.WcfClient"/> <EntitySet Name="WcfService" EntityType="xxx.WcfService"/> <AssociationSet Name="xxx_WcfClient_Application_xxx_SoaApplication_ApplicationPartnerSet" Association="xxx.xxx_WcfClient_Application_xxx_SoaApplication_ApplicationPartner"> <End Role="ApplicationPartner" EntitySet="WcfClient"/> <End Role="Application" EntitySet="SoaApplication"/> </AssociationSet> <AssociationSet Name="xxx_WcfService_Application_xxx_SoaApplication_ApplicationPartnerSet" Association="xxx.xxx_WcfService_Application_xxx_SoaApplication_ApplicationPartner"> <End Role="ApplicationPartner" EntitySet="WcfService"/> <End Role="Application" EntitySet="SoaApplication"/> </AssociationSet> <AssociationSet Name="xxx_WcfService_Clients_xxx_WcfClient_ClientsPartnerSet" Association="xxx.xxx_WcfService_Clients_xxx_WcfClient_ClientsPartner"> <End Role="ClientsPartner" EntitySet="WcfService"/> <End Role="Clients" EntitySet="WcfClient"/> </AssociationSet> </EntityContainer> </Schema> </edmx:DataServices> </edmx:Edmx> 类有一个属性WcfService,我想填充一个与List<WcfClient> Clients相关联的客户列表。

WcfService类看起来像这样:

WcfService

我用于添加对象之间关系的代码如下所示:

[DataServiceKey("ServiceId")]
public class WcfService
{
    [Key]
    public int ServiceId { get; set; }

    ... snip ...

    public List<WcfClient> Clients { get; set; }
}

不幸的是,发生了错误。这是通过线路发送的完整请求和响应(针对命名空间编辑)(来自fiddler)

请求:

   var ctx = new Container(uri);
   var service = ctx.WcfServices.Expand("Clients".Where(i => i.ServiceId == 21).ToArray()[0];
   var client = ctx.WcfClients.Where(i => i.ClientId == 220).ToArray()[0];
   ctx.AddLink(service, "Clients", client);
   ctx.SaveChanges();

响应:

POST http://soa.local.xxx/odata/WcfService(21)/$links/Clients HTTP/1.1
DataServiceVersion: 1.0;NetFx
MaxDataServiceVersion: 3.0;NetFx
Accept: application/atom+xml,application/xml
Accept-Charset: UTF-8
Content-Type: application/xml
User-Agent: Microsoft ADO.NET Data Services
Host: soa.local.xxx
Content-Length: 174
Expect: 100-continue
Connection: Keep-Alive

<?xml version="1.0" encoding="utf-8"?>
<uri xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">http://soa.local.xxx/odata/WcfClient(220)</uri>

我不明白为什么请求网址的格式为HTTP/1.1 404 Not Found Cache-Control: no-cache Pragma: no-cache Content-Type: application/xml; charset=utf-8 Expires: -1 Server: Microsoft-IIS/7.5 DataServiceVersion: 3.0 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Sat, 15 Mar 2014 23:50:12 GMT Content-Length: 565 <?xml version="1.0" encoding="utf-8"?> <m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> <m:code /> <m:message xml:lang="en-US">No HTTP resource was found that matches the request URI 'http://soa.local.xxx/odata/WcfService(21)/$links/Clients'.</m:message> <m:innererror> <m:message>No routing convention was found to select an action for the OData path with template '~/entityset/key/$links/navigation'.</m:message> <m:type></m:type> <m:stacktrace></m:stacktrace> </m:innererror> </m:error> ,错误消息显示为'~/entityset(key)/$links/navigation'

看起来网址中使用的格式在WCF Data Service 4.5中列为支持。但是,我可能会在错误的区域寻找解决方案。

我是否对我应用此更改的方式做错了什么?有没有更合适的方法来编写代码?

由于

1 个答案:

答案 0 :(得分:5)

看起来我需要更彻底地阅读文档。在Working with Entity Relations中,有CreateLinkDeleteLink示例方法。将这些方法添加到Controller后,调用就会成功完成。

我猜路由约定是设置的;但是出现了错误消息,因为没有方法将约定映射到。