【问题标题】:Bound function returns 404绑定函数返回 404
【发布时间】:2014-11-26 06:54:40
【问题描述】:

我正在尝试将绑定函数添加到我的 Web API 2.2 OData v4 控制器,但它返回 404 并显示错误消息:

{
  "error":{
    "code":"","message":"No HTTP resource was found that matches the request URI 'http://localhost:2390/Hierarchies('300924834')/FullHierarchy'.","innererror":{
      "message":"No routing convention was found to select an action for the OData path with template '~/entityset/key/unresolved'.","type":"","stacktrace":""
    }
  }
}

这是我在HierarchiesController上的方法:

[HttpGet]
public IHttpActionResult FullHierarchy([FromODataUri]string key)
{
     return Ok(new Hierarchy());
}

我尝试在我的方法上添加属性[ODataRoute("Hierarchies({key}/FullHierarchy)")],但在第一次运行应用程序时,GlobalConfiguration.Configure(WebApiConfig.Register); 行出现以下错误:

控制器“Hierarchies”中操作“FullHierarchy”的路径模板“Hierarchies({key}/FullHierarchy)”不是有效的 OData 路径模板。错误请求 - 查询语法错误。

这是我在 WebApiConfig 中的配置:

ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

builder.Namespace = ""; // tried with and without this line.

var hierachyType = builder.EntitySet<Hierarchy>("Hierarchies").EntityType;
hierachyType.Function("FullHierarchy").Returns<Hierarchy>();

请注意,绑定到集合的函数效果不佳,但未绑定的函数确实有效。

这就是我的$metadata 的样子:

<?xml version="1.0" encoding="UTF-8"?>
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
    <edmx:DataServices>
        <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Entities.Models">
            <EntityType Name="Hierarchy">
                <Key>
                    <PropertyRef Name="Id" />
                </Key>
                <Property Name="Name" Type="Edm.String" />
                <Property Name="Id" Type="Edm.String" Nullable="false" />
                <NavigationProperty Name="Policy" Type="Entities.Models.Policy" />
                <NavigationProperty Name="Nodes" Type="Collection(Entities.Models.HierarchyNode)" />
            </EntityType>
            <EntityType Name="Node" OpenType="true">
                <Key>
                    <PropertyRef Name="Id" />
                </Key>
                <Property Name="Name" Type="Edm.String" />
                <Property Name="Id" Type="Edm.String" Nullable="false" />
            </EntityType>
            <EntityType Name="Site" BaseType="Entities.Models.Node" OpenType="true">
                <Property Name="Address" Type="Edm.String" />
            </EntityType>
            <EntityType Name="Policy">
                <Key>
                    <PropertyRef Name="Id" />
                </Key>
                <Property Name="Id" Type="Edm.String" Nullable="false" />
                <Property Name="Name" Type="Edm.String" />
                <NavigationProperty Name="Rules" Type="Collection(Entities.Rules.Rule)" />
            </EntityType>
            <EntityType Name="HierarchyNode">
                <Key>
                    <PropertyRef Name="Id" />
                </Key>
                <Property Name="Id" Type="Edm.String" Nullable="false" />
                <Property Name="Name" Type="Edm.String" />
                <NavigationProperty Name="Nodes" Type="Collection(Entities.Models.HierarchyNode)" />
            </EntityType>
            <EntityType Name="Building" BaseType="Entities.Models.Node" OpenType="true">
                <Property Name="StaffCount" Type="Edm.Int32" Nullable="false" />
            </EntityType>
            <EntityType Name="Source" BaseType="Entities.Models.Node" OpenType="true">
                <Property Name="GroupByOperation" Type="Edm.String" />
                <Property Name="Factor" Type="Edm.Int32" Nullable="false" />
            </EntityType>
        </Schema>
        <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Entities.Rules">
            <EntityType Name="Rule" Abstract="true">
                <Key>
                    <PropertyRef Name="Id" />
                </Key>
                <Property Name="Id" Type="Edm.String" Nullable="false" />
                <Property Name="Name" Type="Edm.String" />
                <Property Name="NodeType" Type="Edm.String" />
            </EntityType>
            <EntityType Name="ParentChildRule" BaseType="Entities.Rules.Rule">
                <Property Name="AllowedParentsTypes" Type="Edm.String" />
                <Property Name="ForbiddenParentsTypes" Type="Edm.String" />
            </EntityType>
            <EntityType Name="PredicateRule_1OfTNode" BaseType="Entities.Rules.Rule">
                <Property Name="Predicate" Type="System.Linq.Expressions.Expression_1OfFunc_2OfTNode_String" />
            </EntityType>
            <EntityType Name="PropertyRule" BaseType="Entities.Rules.Rule">
                <Property Name="RequiredProperties" Type="Edm.String" />
            </EntityType>
        </Schema>
        <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="System.Linq.Expressions">
            <ComplexType Name="Expression_1OfFunc_2OfTNode_String">
                <Property Name="Parameters" Type="Collection(System.Linq.Expressions.ParameterExpression)" />
            </ComplexType>
            <ComplexType Name="ParameterExpression" />
        </Schema>
        <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm">
            <Function Name="FullHierarchy" IsBound="true">
                <Parameter Name="bindingParameter" Type="Entities.Models.Hierarchy" />
                <ReturnType Type="Entities.Models.Hierarchy" />
            </Function>
            <EntityContainer Name="Container">
                <EntitySet Name="Hierarchies" EntityType="Entities.Models.Hierarchy" />
                <EntitySet Name="Nodes" EntityType="Entities.Models.Node" />
                <EntitySet Name="Sites" EntityType="Entities.Models.Site" />
                <EntitySet Name="Rules" EntityType="Entities.Rules.Rule" />
            </EntityContainer>
        </Schema>
    </edmx:DataServices>
</edmx:Edmx>

【问题讨论】:

    标签: c# asp.net .net asp.net-web-api odata


    【解决方案1】:

    有几件事:

    1. 架构需要有一个命名空间。 IE。 builder.Namespace = ""; 需要删除或替换为非空字符串。
    2. 该函数需要通过它的完全限定名称来调用。 IE。请求 URL 必须是 http://localhost:2390/Hierarchies('300924834')/&lt;namespace&gt;.FullHierarchy,其中 &lt;namespace&gt; 应该是默认命名空间或您在第 1 项中指定的命名空间。
    3. 作为绑定到单个实体的函数,像这样编写控制器方法就足够了: [HttpGet] public IHttpActionResult FullHierarchy() { return Ok(new Hierarchy()); } 我不知道确切的原因。我猜约定模型构建器可以帮助您进行此类路由。

    它适用于我,以下是我的测试功能详细信息:

    WebApiConfig:

    builder.EntityType<Product>().Function("SomeFunction").Returns<string>();
    

    在 ProductsController 中:

    [HttpGet]
        public IHttpActionResult SomeFunction()
        {
            return Ok("Some");
        }
    

    请求:

    GET http://localhost:54017/Products(1)/Default.SomeFunction
    

    【讨论】:

    • 谢谢 Yi,我不知道命名空间是必需的。另外我不明白你在第 3 节中的意思。顺便问一下,你知道为什么命名空间只对有界函数是必需的吗?
    • @gdoron 我认为所有类型的函数都需要它:绑定、未绑定和函数导入。对于第 3 节,我实际上是说您不需要“[FromODataUri] 字符串键”作为代表函数的控制器方法的参数。
    • 1.我确实设法在没有命名空间的情况下调用了未绑定的函数。 2.但如果是绑定函数,我必须得到实体的键。 3.无关的,你知道这个答案吗:groups.google.com/forum/m/#!topic/odata-discussion/zGP2wDYUmaE
    • 没有办法省略命名空间吗?目前,我将一个动作称为/Operations(1)/Default.Abort,但最好有/Operations(1)/Abort 有没有办法做到这一点?
    猜你喜欢
    • 1970-01-01
    • 2017-02-26
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    相关资源
    最近更新 更多