【问题标题】:API multiple Get methods and routingAPI 多个 Get 方法和路由
【发布时间】:2014-05-22 21:27:33
【问题描述】:

我有一个只有 Get 方法的控制器

public class DeviceController : ApiController
{
    List<Device> machines = new List<Device>();

    public IEnumerable<Device> GetAllMachines()
    {
        //do something
        return machines;
    }

    [HttpGet]
    public IEnumerable<Device> GetMachineByID(int id)
    {
        //do something
        return machines;
    }

    [HttpGet]
    public IEnumerable<Device> GetMachinesByKey(string key)
    {
        //do something
        return machines;
    }

}

我希望能够通过 URL 访问这些并取回数据

../api/{contorller}/GetAllMachines
../api/{contorller}/GetMachineByID/1001
../api/{contorller}/GetMachiesByKey/HP (machines exist)

当我在 IE 开发人员模式 (f12) 中运行前两个时,我得到 Json,显示所有机器和机器 1001。但是当我运行 GetMachinesByKey/HP 时,我得到 404 错误。

我的 WebApiConfig 也是这样的

        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        config.Routes.MapHttpRoute(
            name: "ActionApi",
            routeTemplate: "api/{controller}/{Action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

有人告诉我我做错了什么吗?

【问题讨论】:

  • 看看这篇文章,或许能帮到你。 asp.net/web-api/overview/web-api-routing-and-actions/…
  • 我认为路由引擎希望绑定到路由配置中定义的名为id 的变量;您的操作参数被命名为 key,因此框架不会为您连接这些点。
  • @DaveParsons 是对的。

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


【解决方案1】:

路由引擎期望绑定到路由配置中定义的名为 id 的变量:

config.Routes.MapHttpRoute(
    name: "ActionApi",
    routeTemplate: "api/{controller}/{Action}/{id}", //<--- here {id} means bind to parameter named 'id'
    defaults: new { id = RouteParameter.Optional }
);

在您的操作中,GetMachinesByKey(string key) 参数被命名为 key,因此框架不会为您连接这些点。

您可以在查询字符串中传递参数,因此使用 /api/{contorller}/GetMachiesByKey/?key=HP 形式的 URL 将正确绑定(您可能需要更改路由配置,因为这不会传递当前配置的 id 参数期待)。

另外,我相信您可以使用attribute routing 为操作指定路线。这允许您使用一个属性来装饰您的操作方法,该属性告诉框架应该如何解析路由,例如:

[Route("<controller>/GetMachinesByKey/{key}")]
public IEnumerable<Device> GetMachinesByKey(string key)

【讨论】:

  • 谢谢您的解释,我已经在控制器中添加了路由,我可以访问数据了
【解决方案2】:

使用 RoutePrefix 和 Route 属性。

[RoutePrefix("api/device")]
public class DeviceController : ApiController
{
List<Device> machines = new List<Device>();

[HttpGet]
[Route("Machines")]
public IEnumerable<Device> GetAllMachines()
{
    //do something
    return machines;
}

[HttpGet]
[Route("Machines/{id:int}")]
public IEnumerable<Device> GetMachineByID(int id)
{
    //do something
    return machines;
}

[HttpGet]
[Route("Machines/{key}")]
public IEnumerable<Device> GetMachinesByKey(string key)
{
    //do something
    return machines;
}

【讨论】:

  • 这有帮助,谢谢 - 添加这些后,我的 WebApiConfig 就不需要了,还是?
  • config.MapHttpAttributeRoutes 就足够了。
猜你喜欢
  • 2020-05-27
  • 1970-01-01
  • 1970-01-01
  • 2012-09-28
  • 2017-04-19
  • 2021-08-06
  • 1970-01-01
  • 2021-01-11
  • 2018-09-28
相关资源
最近更新 更多