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

ata*_*ati 12 asp.net routing asp.net-web-api

这是我的路由配置:

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

而且,这是我的控制器:

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...
    }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试时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."
}
Run Code Online (Sandbox Code Playgroud)

Ana*_*nni 15

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

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

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

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

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

这是因为该方法在请求api/Products/Product/test时期望参数id, 而不是查找name参数.


Dal*_*rzo 7

根据您的更新:

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

因此,为了匹配这个api/Products/Product/test基于此模板的 "api/{controller}/{action}/{id}"YOur方法需要声明如下:

[ActionName("Product")]
[HttpGet]
public object Product(string id){
   return id;
}
Run Code Online (Sandbox Code Playgroud)

参数string name被替换的位置string id.

这是我的完整样本:

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

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

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

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