asp.net Web Api路由无法正常工作

时间:2014-02-13 17:05:36

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

这是我的路由配置:

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

而且,这是我的控制器:

public class ProductsController : ApiController
{
    [AcceptVerbs("Get")]
    public object GetProducts()
    {
       // return all products...
    }

    [AcceptVerbs("Get")]
    public object Product(string name)
    {
       // return the Product with the given name...
    }
}

当我尝试api/Products/GetProducts/时,它有效。 api/Products/Product?name=test也有效,但api/Products/Product/test不起作用。我做错了什么?

更新

这是我尝试api/Products/Product/test时得到的结果:

{
  "Message": "No HTTP resource was found that matches the request URI 'http://localhost:42676/api/Products/Product/test'.",
  "MessageDetail": "No action was found on the controller 'Products' that matches the request."
}

3 个答案:

答案 0 :(得分:15)

这是因为您的路由设置及其默认值。你有两个选择。

1)通过更改路由设置以匹配Product()参数以匹配URI。

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

2)另一种推荐的方法是使用正确的方法签名属性。

public object Product([FromUri(Name = "id")]string name){
       // return the Product with the given name
}

这是因为该方法在请求时需要参数 id api / Products / Product / test 而不是寻找名称参数。

答案 1 :(得分:7)

根据您的更新:

  

请注意 WebApi 基于反射工作,这意味着您的花括号{vars}必须与您的方法中的相同名称匹配。

因此,要根据此模板匹配此api/Products/Product/test "api/{controller}/{action}/{id}",您需要将此方法声明为:

[ActionName("Product")]
[HttpGet]
public object Product(string id){
   return id;
}

参数string namestring id替换。

以下是我的完整样本:

public class ProductsController : ApiController
{
    [ActionName("GetProducts")]
    [HttpGet]
    public object GetProducts()
    {
        return "GetProducts";
    }
    [ActionName("Product")]
    [HttpGet]
    public object Product(string id)
    {
        return id;
    }
}

我尝试使用完全不同的模板:

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

但它在我的结尾工作得很好。顺便说一下,我删除了[AcceptVerbs("Get")]并将其替换为[HttpGet]

答案 2 :(得分:1)

您的路由是将id定义为参数,但您的方法需要name参数。如果可以,我更喜欢属性路由,然后在Product方法上定义/ api / products / product / {name}。

http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2