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

时间:2018-03-08 12:32:46

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

我是OData的新手。出于学习目的(由this教程指导),我已经设置了一个示例WebApi,如下所示(仅粘贴我认为相关的内容)。

配置:

使用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;
    }
}

模型类:

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; }
  }
}

控制器:

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

现在我试图按照documentation中给出的矩阵,看看这实际上是多么有能力。不幸的是,我无法通过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

有人看到我的错误(......并且愿意告诉我)吗?

1 个答案:

答案 0 :(得分:0)

在这个问题上度过了相当长的一段时间之后,我偶然发现了related post在这里。

OData docs提供的路由约定非常明确(第3.2节 - 内置路由约定): enter image description here

因此,我必须做的就是让内置约定工作,将我的方法参数从id重命名为key

嵌套路线(entityset(key)下方),如here所述,仍无效。我已经决定为此开启另一个问题。

示例:

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