具有多个参数的OData控制器方法

时间:2020-09-06 01:05:20

标签: c# api odata custom-routing

我需要使用此分配创建一个OData控制器。

http:// xxxxxx / odata / mock / Itens(NumContrato ='1234',IdItem = '10')/ Pedidos

ItensController

public class ItensController : ODataController
{
    [HttpPost]
    [ODataRoute("(NumContrato={NumContrato},IdItem={IdItem})/Pedidos")]
    public IQueryable<Pedido> Pedidos([FromODataUri] string NumContrato, [FromODataUri] string IdItem)
    {
        ... do something
    }
}

WebApiConfig.cs

...
config.Routes.MapODataServiceRoute(
        "ODataRoute",
        "odata/mock",
        model: GetModel(),
        new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
...

public static IEdmModel GetModel()
{
    ODataModelBuilder builder = new ODataConventionModelBuilder();
    ...
    builder.EntitySet<Dominio.ODataSapFake.Item>("Itens");
    builder.EntitySet<Dominio.ODataSapFake.LinhaDeServico>("LinhasDeServicos");
    builder.EntitySet<Dominio.ODataSapFake.Pedido>("Pedidos");
    var a = builder.Entity<Dominio.ODataSapFake.Item>().Collection.Action("Pedidos");
    a.Parameter<string>("NumContrato");
    a.Parameter<string>("IdItem");
    a.ReturnsCollectionFromEntitySet<Dominio.ODataSapFake.Pedido>("Pedidos");
    ...
    return builder.GetEdmModel();
}

呼叫服务时发生错误

<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://localhost:4492/odata/mock/Itens(NumContrato='100',IdItem='00040')/Pedidos'.
    </m:message>
    <m:innererror>
        <m:message>No routing convention was found to select an action for the OData path with template '~/entityset/key/navigation'.
        </m:message>
        <m:type/>
        <m:stacktrace/>
    </m:innererror>
</m:error>

1 个答案:

答案 0 :(得分:1)

您的URL不正确,或者您的配置不正确,请探讨两种可能性:

假设配置正确,您已经声明名为Pedidos Action 有2个参数,并且绑定到 collection ,否绑定到任何项目...符合您定义的网址实际上是:

~/Itens/Pedidos(NumContrato='1234',IdItem='10')

假设URL是正确的,那么您需要将端点配置为与 Item 绑定的 Action ,并且我们还假设Itens记录已经具有定义的键NumContratoIdItem

builder.EntitySet<Dominio.ODataSapFake.LinhaDeServico>("LinhasDeServicos");
builder.EntitySet<Dominio.ODataSapFake.Pedido>("Pedidos");
var itens = builder.EntitySet<Dominio.ODataSapFake.Item>("Itens");
// Key should be defined by attribute notation, but we can redefine it here for clarity
itens.EntityType.HasKey(x => x.NumContrato);
itens.EntityType.HasKey(x => x.IdItem);
// declare the Action bound to an Item
itens.Item.Action("Pedidos")
    .ReturnsCollectionFromEntitySet<Dominio.ODataSapFake.Pedido>("Pedidos");

更新1-GET支持:

Action 支持HTTP Post,OP对此方法进行了修饰,但是如果您打算支持HTTP GET,则必须将端点配置为 Function 。语法仍然相同。

  • 不要忘记删除[HttpPost]属性,考虑将其替换为[EnableQuery][HttpGet]

更新2-使用组合键的项目导航

如果Item数据记录具有名为Pedidos的导航属性,并且您打算支持该属性路径下的标准项导航,则无需在配置全部中包括此信息。

  • 删除[HttpPost],这是一个GET请求。
  • 删除[ODataRoute]属性,默认路由应该起作用
  • 确保使用键属性的名称,并使用与配置中声明的相同的大小写和顺序。
    • 如果您使用的是自动配置,那么顺序将与数据模型中的Key属性列规范匹配。
  • 对于OData v3,您可能需要遵循以下建议:Odata v3 Web Api navigation with composite key