Reputation: 613
I am new into WebAPI and I don't understand how routing in WebAPI v2 works.
I've created simple test controller:
public class TestController : ApiController
{
public List<string> GetAll()
{
return new List<string>();
}
public string Get(int id)
{
return string.Empty;
}
public string GetSmthByParam1(int param)
{
return string.Empty;
}
public string GetSmthByParam2(int param)
{
return string.Empty;
}
public List<string> GetAllByParam(int param)
{
return new List<string>();
}
}
I would like to reach each method by:
/Api/Test/GetAll
/Api/Test/Get/3
/Api/Test/GetSmthByParam1/1
/Api/Test/GetSmthByParam2/1
/Api/Test/GetAllByParam/1
and I don't know how to achieve it. I changed routes in WebApiConfig.cs to:
config.Routes.MapHttpRoute("DefaultApiWithAction", "Api/{controller}/{action}/{id}", new { id = RouteParameter.Optional }, new { id = @"\d+" });
Upvotes: 1
Views: 1249
Reputation: 1
Attribute routing is something which you should look for. It simplifies your Api in a much better way and you never have to keep guessing looking at your route map in ApiConfig that which route is getting resolved. There are discussions around whether you should opt for Attribute routing or not, but in my opinion it really depends on how simple and readable you want your API to be. Happy coding.
Upvotes: 0
Reputation: 752
Install Nuget-Package AttributeRouting.WebAPI
Do not touch default route in a WebApiConfig
Add "config.MapHttpAttributeRoutes();" into Register method of the WebApiConfig class, so it would be:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
...
}
}
Now you could add a RouteAttrubute to any webapi action like this:
[HttpGet]
[AllowAnonymous]
[Route("api/test/get/{id}")]
public string Get(int id)
{
return string.Empty;
}
These links will be useful: first & second
Upvotes: 3
Reputation: 2092
You do not need to use attribute routing. Just add an http verb attribute to your methods and change 'param' to 'id' on a few of the methods.
public class TestController : ApiController
{
[HttpGet]
public List<string> GetAll()
{
return new List<string>();
}
[HttpGet]
public string Get(int id)
{
return string.Empty;
}
[HttpGet]
public string GetSmthByParam1(int id)
{
return string.Empty;
}
[HttpGet]
public string GetSmthByParam2(int id)
{
return string.Empty;
}
[HttpGet]
public List<string> GetAllByParam(int id)
{
return new List<string>();
}
}
Upvotes: 0
Reputation: 11
The default routing mechanism in WebAPI try to play the CRUD attitude. This is all about this..
When it fits your needs - go for it. Usually, better approach would be to you the Attributes
(like Rakesh wrote).
It arranges your controllers in better way and much easier to expect the URLs..
Upvotes: 0
Reputation: 384
To be very short, webapi will go for the signature rather than just a name of the action like mvc routing works, so to solution for this dilemma would be
1) MVC5 comes with attribute routing so one can define it at the action or the controller level to make it more easy
2) make your signature unique to eachother along with the reqeust type with normal routing but if your routing has same signature then do something like this
define your routing like this,
config.Routes.MapHttpRoute(
name: "Defaultapi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Upvotes: 0
Reputation: 4516
Although I know that this is a basic example you put forward, I'm interested in your actual business case a little more. Why does your controller many GETS? There is nothing wrong with that, keep in mind, i'm simply curious. Oftentimes I've been able to avoid multiple gets with concepts such as ODATA queries, strategy patterns, or services that are able to retrieve what is needed. Route attributes are a great solution to this as others mentioned, however as someone else mentioned it could potentially be a problem where you have to start using a route prefix on the controller coupled with route attributes to sometimes make the route more clear, and it can get a little messy fast (i've had my teams sometimes do that where they didn't follow convention correctly and their controller routes weren't intuitive)
Finally, what are the return types that you'll have for these - are they really all string?
Thanks!
Upvotes: 0
Reputation: 1
So it is nice to use Attribute routes, but i'll suggest don't do it right now, as it encapsulates lot of logic which you have to learn right now. Plus I don't think attribute route is good practice every time. Some times routes from config is better choice, when you are building really huge application. Now see you route config your parameter is "id" so when route will hit it will extract your parameter and it will inject it to your method. in your last 3 methods you have used "param", as your method parameter, which is something route will not be able to inject. as names don;t match in route param and method param. further more, if you will create another route similar to previous one and change the route parameter to "param", it will still don't work, because route mapping works on first come first basis. I hope you would have got little start on this and you will understand the importance of learning routing basics along with the using attributes.
Upvotes: 0
Reputation: 157
below code should work for you,
[RoutePrefix("Test")]
public class TestController : ApiController
{
[Route("GetAll")]
public List<string> GetAll()
{
return new List<string>();
}
[Route("Get")]
public string Get(int id)
{
return string.Empty;
}
[Route("GetSmthByParam1/{param}")]
public string GetSmthByParam1(int param)
{
return string.Empty;
}
[Route("GetSmthByParam2/{param}")]
public string GetSmthByParam2(int param)
{
return string.Empty;
}
[Route("GetSmthByParam/{param}")]
public List<string> GetAllByParam(int param)
{
return new List<string>();
}
}
Your config should be
config.MapHttpAttributeRoutes();
Upvotes: 4
Reputation: 2323
You should use Route attribute see the article here: http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2
Upvotes: 0