简体   繁体   English

odata webapi路由问题:标识符不匹配的get方法

[英]odata webapi routing issue: get method with identifier not matched

I am new to OData. 我是OData的新手。 For learning purposes (guided by this tutorial), I have set up a sample WebApi like the following (Only pasting what I consider relevant). 出于学习目的(在教程的指导下),我建立了一个类似于以下示例的WebApi(仅粘贴我认为相关的内容)。

Configuration: 组态:

using DataApi.Models; 使用DataApi.Models;

using Microsoft.OData.Edm;
using System.Net.Http.Headers;
using System.Web.Http;
using System.Web.OData.Batch;
using System.Web.OData.Builder;
using System.Web.OData.Extensions;

public static class WebApiConfig
{ 
 public static void Register(HttpConfiguration config)
    {
      config.MapODataServiceRoute("od", null, GetEdmModel(), new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
      config.Count()
        .Filter()
        .OrderBy()
        .Expand()
        .Select()
        .MaxTop(null);     
    }

 private static IEdmModel GetEdmModel()
    {
      ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
      builder.Namespace = "Demos";
      builder.ContainerName = "DefaultContainer";
      builder.EntitySet<Code>("Code");      
      var edmModel = builder.GetEdmModel();
      return edmModel;
    }
}

The Model Classes: 模型类:

using System.ComponentModel.DataAnnotations;

namespace DataApi.Models
{
  public class Code
  {

    [Key]
    public long Id { get; set; }

    [Required]
    public string Value { get; set; }

    public Validity Validity { get; set; }
    public Code Parent { get; set; }
  }
}

namespace DataApi.Models
{
  public class Validity
  {
    [Key]
    public long Id { get; set; }
    [Required]
    public DateTime From { get; set; }
    [Required]
    public DateTime To { get; set; }
  }
}

The Controller: 控制器:

using DataApi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.OData;

namespace DataApi.Controllers
{
  [EnableQuery]
  public class CodeController : ODataController
  {
    private List<Code> _codes;

    public CodeController()
    {
      _codes = new List<Code>();

      Validity validity = new Validity()
      {
        From = new DateTime(2018, 1, 1),
        To = new DateTime(2018, 12, 31)
      };
      Code code1 = new Code() { Id = 1, Value = "1", Validity = validity };

      _codes.Add(code1);
      _codes.Add(new Code() { Id = 2, Value = "1.1", Parent = code1, Validity = validity });
      _codes.Add(new Code() { Id = 3, Value = "1.2", Parent = code1, Validity = validity });
      _codes.Add(new Code() { Id = 4, Value = "1.3", Parent = code1, Validity = validity });
      _codes.Add(new Code() { Id = 5, Value = "1.4", Parent = code1, Validity = validity });
      _codes.Add(new Code() { Id = 6, Value = "1.5", Parent = code1, Validity = validity });
      _codes.Add(new Code() { Id = 7, Value = "1.6", Parent = code1, Validity = validity });
      _codes.Add(new Code() { Id = 8, Value = "1.7", Parent = code1, Validity = validity });
      _codes.Add(new Code() { Id = 9, Value = "2", Validity = validity });

    }

    public IHttpActionResult Get()
    {
      return Ok(_codes.AsQueryable());
    }

    public IHttpActionResult Get(string id)
    {
      long idNumeric = Convert.ToInt64(id);
      return Ok(_codes.AsQueryable().First(x => x.Id == idNumeric));
    }
  }
}

Now I'm trying to follow the matrix given in the documentation , to see how capable this actually is. 现在,我尝试遵循文档中给出的矩阵,以了解其实际功能。 Unfortunately, I cannot query my object by Id 不幸的是,我无法通过ID查询对象

http://localhost:54307/Code?$expand=Validity          //--> works
http://localhost:54307/Code?$select=Value             //--> works
http://localhost:54307/Code(1)                        //--> selects the entire list
http://localhost:54307/Code?$filter=Value eq "1.1"    //--> works

Does anybody see my mistake (...and is willing to tell me about it)? 是否有人看到我的错误(...并愿意告诉我)?

After having spent quite some time with this issue, I stumbled across a related post here on SO. 在花了很多时间解决这个问题之后,我偶然发现了一篇有关 SO的相关文章

The routing convention as provided by OData docs is pretty explicit(Section 3.2 - Built-in routing conventions): OData文档提供的路由约定非常明确(第3.2节-内置路由约定): 在此处输入图片说明

So, what I had to do to get the built-in convention working was rename my method argument from id to key . 因此,要使内置约定正常工作,我要做的就是将方法参数从id重命名为key

Nested routes (below entityset(key) ) like the ones stated here are still not working. 类似于此处所述的嵌套路由(在entityset(key)之下entityset(key)仍然无法使用。 I've decided to open another issue for this. 我已决定为此打开另一个问题。

Example: 例:

http://localhost:52072/Code(5)/Value

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

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