简体   繁体   English

OData Web API路由

[英]OData Web API routing

I have a web API exposing ODATA from a SQL stored proc. 我有一个Web API,它从SQL存储过程中公开ODATA。 I want to use a url like /odata/firmhierarchy(225) to pass 225 into a param for the stored proc. 我想使用/ odata / firmhierarchy(225)这样的网址,以将225传递到存储过程的参数中。 It just tells me that it can't find a matching resource. 它只是告诉我找不到匹配的资源。 It hits the controller, just skips the method. 它命中了控制器,只是跳过了方法。 Thoughts? 有什么想法吗?

In webapiconfig 在webapiconfig中

        private static IEdmModel GenerateEdmModel()
    {
        var builder = new ODataConventionModelBuilder();
        builder.EntitySet<Employee>("Employees");
        builder.EntitySet<Employee>("FirmHierarchy");

        return builder.GetEdmModel();
    }

Context: 内容:

    public virtual ObjectResult<Employee> sp_EmployeeHierarchy(Nullable<int> managerEmpID)
    {
        var managerEmpIDParameter = managerEmpID.HasValue ?
            new SqlParameter("ManagerEmpID", managerEmpID) :
            new SqlParameter("ManagerEmpID", 0);

        return ((IObjectContextAdapter)this).ObjectContext.ExecuteStoreQuery<Employee>("sp_EmployeeHierarchy @ManagerEmpID", managerEmpIDParameter);
    }

Only method in controller: 控制器中的唯一方法:

    [Queryable]
    public IQueryable<Employee> GetFirmHierarchy()
    {
        return db.sp_EmployeeHierarchy(225).AsQueryable();
        //return SingleResult.Create(db.Employees.Where(employee => employee.EmpId == key));
    }

This should work: 这应该工作:

1.Write another method in your controller: 1.在控制器中写另一种方法:

[EnableQuery]
public IQueryable<Employee> Get([FromODataUri] int key)
{
    return db.sp_EmployeeHierarchy(key).AsQueryable();
}

Please note that [EnableQuery] is an attribute introduced in Web API for OData V4. 请注意, [EnableQuery]是OAPI V4的Web API中引入的属性。 If you are still using Web API for OData V1-3, use [Queryable] still. 如果仍将Web API用于OData V1-3,请仍然使用[Queryable]

2.Then you can send the request 2.然后您可以发送请求

GET /odata/firmhierarchy(225)

and get the employees. 并得到员工。

I was able to make ODATA work for a table, when auto-generated from entity framework. 从实体框架自动生成时,我能够使ODATA适用于表。 However, that generation process didn't want to work for a complex type returned by a Table Valued Function (similar scenario to a SP), because it didn't seem to understand where the key was. 但是,该生成过程不想为表值函数返回的复杂类型(类似于SP的情况)工作,因为它似乎不了解键在哪里。

What I found was that I could however make it work. 我发现我可以使它起作用。 First, I check out this article . 首先,我查看这篇文章 He sets things up a bit more manually, where his Get on a companyProcessing Controller ends up routing for id 3 as " http://localhost:10020/odata/ companyProcessing (3)" . 他更多的手动设定了一点东西,他的上companyProcessing控制器获取最终的路由的ID 3“ 的http://本地主机:10020 /的OData / companyProcessing(3)”。

This surprised me. 这让我感到惊讶。 My other generated classes set up the pattern that SomeEntity became SomeEntityController, with methods like GetSomeEntities, and a routing that seemed to me to match the method but dropping the word get. 我生成的其他类使用诸如GetSomeEntities之类的方法,设置了SomeEntity成为SomeEntityController的模式,以及对我来说似乎与该方法匹配的路由,但删除了单词get。 Therefore, dropping the entity name from the Get method name seemed different, but it worked. 因此,从Get方法名称中删除实体名称似乎有所不同,但是可以。 Proving that the path is actually matching the controller name, not the method name. 证明路径实际上与控制器名称匹配,而不与方法名称匹配。

In this Case you configure the routing using the data type you're querying for, and the beginning of the controller name. 在这种情况下,您可以使用查询的数据类型以及控制器名称的开头来配置路由。 Then the actual path utilizes the beginning of the controller name as well. 然后,实际路径也将使用控制器名称的开头。

And then all of this just brings us essentially to the other posted solution, assuming your controller name is firmhierarchy Controller 然后,假设您的控制器名称为firmhierarchy ,所有这些基本上就将我们带到了其他已发布的解决方案中

So, now, making sense of this... Try going to http://localhost:55063/odata/ $metadata , where your port may differ. 因此,现在,了解这一点...尝试转到http:// localhost:55063 / odata / $ metadata,您的端口可能会有所不同。 You'll notice that ODATA exposes a DataType , which is accessed via a DataSet . 您会注意到,ODATA公开了一个DataType ,可以通过DataSet进行访问。 When a client tries to query into ODATA, they are trying to query against the DataSet, getting items of the DataType. 当客户端尝试查询ODATA时,他们尝试针对DataSet查询,获取DataType的项。

The DataSet matching the controller name (less Controller), and the Get methods can indeed just be Get without further extension of the name - and otherwise in this scenario was giving me problems. 与控制器名称(较少的Controller)匹配的DataSet和Get方法的确可以是Get,而无需进一步扩展名称-否则在这种情况下会给我带来麻烦。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM