ActionName的ASP.Net Web Api路由问题

时间:2014-01-06 00:29:24

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

我正在使用Web Developer Express 2010上的ASP.Net Web Api项目。路由配置在WebApiConfig.cs中定义为:

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

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

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

名为“GCURObservationController”的API控制器的操作如下:

[HttpGet, ActionName("retrieveCuringMaps")]
    public IList<SimpleCuringMapsModel> retrieveCuringMaps()
    {
        ... ...
        return jsonCuringMapModels;
    }

项目已编译并成功运行。但是,我不得不去

http://localhost:2061/api/GCURObservation/retrieveCuringMaps/0

触发操作(操作名称后跟任何整数),而不是我预期的

http://localhost:2061/api/GCURObservation/retrieveCuringMaps

这意味着任意整数必须遵循操作名称才能使其正确。否则,返回错误。我不希望任何参数触发此操作。

{"Message":"The request is invalid."}

如何让第二个网址生效?感谢

干杯, 亚历

1 个答案:

答案 0 :(得分:2)

如果您使用的是Web API 2,以下是您可以使用的解决方案。在下面的示例中,我在一个控制器中一起使用属性路由和传统路由。此处除了GetCustomerOrders之外的所有操作都是通过常规路由“DefaultApi”到达的。

一般来说,这里的想法并不新鲜,即使没有Web API 2的属性路由,您可以在全局路由表中为控制器的每个单独操作定义路由,但属性路由使此过程更容易你可以直接和靠近行动定义路线。

config.MapHttpAttributeRoutes();

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

[RoutePrefix("api/customers")]
public class CustomersController : ApiController
{
    public IEnumerable<Customer> GetAll()
    {
    }

    public Customer GetSingle(int id)
    {
    }

    public void Post(Customer customer)
    {
    }

    public void Put(int id, Customer updatedCustomer)
    {
    }

    public void Delete(int id)
    {
    }

    [Route("{id}/orders")]
    public IEnumerable<Order> GetCustomerOrders(int id)
    {
    }
}