asp.net Web Api routing not working

心不动则不痛 提交于 2019-12-03 10:12:14

问题


Here is my routing configuration:

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

And, here is my controller:

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...
    }
}

When I try api/Products/GetProducts/, it works. api/Products/Product?name=test also works, but api/Products/Product/test does not work. What am I doing wrong?

UPDATE:

Here's what I get when I try 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."
}

回答1:


This is because of your routing settings and its default values. You have two choices.

1) By changing the route settings to match the Product() parameter to match the URI.

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

2) The other and recommended way is to use the correct method signature attribute.

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

This is because the method is expecting a parameter id when requesting api/Products/Product/test rather than looking for a name parameter.




回答2:


Based on your update:

Please note that WebApi works based on reflection this means that your curly braces {vars} must match the same name in your methods.

Therefore to match this api/Products/Product/test based on this template "api/{controller}/{action}/{id}" YOur method needs to be declare like this:

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

Where the parameter string name was replaced by string id.

Here is my full sample:

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

I tried using a totally different template:

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

But it worked fine on my end. Btw I additional removed [AcceptVerbs("Get")] and replaced them with [HttpGet]




回答3:


Your route is defining id as the parameter yet your method expects a name parameter. I prefer attribute routing if you can, then define /api/products/product/{name} on the Product method.

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



来源:https://stackoverflow.com/questions/21760762/asp-net-web-api-routing-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!