【问题标题】:WebAPI 2 OData - No routing convention for '~/entityset/key/$links/navigation'WebAPI 2 OData - '~/entityset/key/$links/navigation' 没有路由约定
【发布时间】:2014-04-21 07:51:40
【问题描述】:

我对 OData 和 WebAPI 2 还很陌生。很抱歉。

我的目标是使用具有WcfService 对象和WcfClient 对象公开的OData 服务,并通过列表属性ClientsWcfClientWcfService 相关联。 (例如service.Clients.Add(client) 但使用 OData 服务)

我有一个带有 WcfServiceWcfClientSoaApplication 类的 EF 代码优先数据库。并且,使用 Microsoft.AspNet.WebApi.OData 5.1.1 设置 OData Web 服务。链接所有内容的代码都是使用 VS2013 中的向导设置的。 OData 端点的 $metadata 如下所示 (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&lt;WcfClient&gt; Clients,我想用与WcfService 关联的客户端列表填充该属性。

WcfService 类看起来有点像这样:

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

    ... snip ...

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

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

   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();

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

请求:

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>

我不明白为什么请求url的格式是'~/entityset(key)/$links/navigation'而错误信息是'~/entityset/key/$links/navigation'

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

我应用更改的方式有问题吗?有没有更合适的方式来编写代码?

谢谢

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 2019-11-27
      • 2014-09-04
      • 2017-03-13
      • 2014-03-01
      • 2019-12-26
      • 1970-01-01
      相关资源
      最近更新 更多