ASP.NET Web API路由无法工作

12

这是我的路由配置:

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个回答

16

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

1)将路由设置更改为与URI匹配的Product()参数匹配。

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
}

这是因为当请求api/Products/Product/test时,该方法需要一个名为id的参数,而不是寻找name参数。


1
好的,看起来你需要指定名称,像这样:public object Product([FromUri(Name = "id")]string name) - ataravati
感谢推荐的方法! - ataravati
对我很有用!我想在字符串中使用不同的参数,但在webapiconfig文件中被定义为“id”,你的建议解决了这个问题!非常感谢。 - superachu

7

根据您的更新:

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

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

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

在参数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;
    }
}

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

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

但是在我的端上它能正常工作。顺便我还额外删掉了 [AcceptVerbs("Get")] 并用 [HttpGet] 替换了它们。


@ataravati,在我的端上它工作正常。你有出现错误吗? - Dalorzo
感谢您的解释!我更改了参数名称,它已经起作用了。 - ataravati

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接