API multiple Get方法和路由

时间:2014-05-22 13:08:56

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

我有一个只有Get Methods的控制器

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

任何人都会告诉我我做错了什么?

2 个答案:

答案 0 :(得分:0)

路由引擎期望绑定到路由配置中定义的名为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形式的网址将正确绑定(您可能需要更改路由配置,因为这不会传递id参数当前配置将是期待的)。

或者我相信您可以使用attribute routing为行动指定路线。这允许您使用一个属性来装饰您的action方法,该属性告诉框架应该如何解析路径,例如:

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

答案 1 :(得分:0)

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