Think about your HTTP request -- how will the runtime (with the default routes) distinguish which action method to invoke? Routing (and thus the URL) does not contain the action name. If you want this, then define a custom route with the action name in the
URL, but that goes somewhat counter to the design of WebAPI and action method mapping based upon the HTTP method.
If you want this, then define a custom route with the action name in the URL, but that goes somewhat counter to the design of WebAPI and action method mapping based upon the HTTP method.
You're right that the Web API project templates steer you down the route of RESTful controllers... but I'm not sure there is anything wrong
per se with writing more RPC style APIs. Sometimes its the right thing to do.
You're right that the Web API project templates steer you down the route of RESTful controllers... but I'm not sure there is anything wrong
per se with writing more RPC style APIs. Sometimes its the right thing to do.
Well, I don't want to get into a philosophical debate on how to use the framework. I was simply pointing out that the way the plumbing works by default is to prefer only one of each HTTP method per API controller. You can circumvent this by augmenting the
routing table.
I have been follow all the way others ppl tutorial but it's get stuck.
RouteConfig
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Controller
public class ValuesController : ApiController
{
public Msg Hello(Msg model)
{
return model;
}
public Msg HelloAgain(Msg model)
{
return model;
}
}
public class Msg
{
public string msgContent { get; set; }
}
Fiddler Post it's return me this
"Multiple actions were found that match the request: \r\nTest.Controllers.Msg Hello(Test.Controllers.Msg) on type Test.Controllers.ValuesController\r\nTest.Controllers.Msg HelloAgain(Test.Controllers.Msg) on type Test.Controllers.ValuesController"
Your example URIs are both matching each other. Look more carefully at the rule. The query string is not part of the route. They are matching api/{controller}/{id} with a controller of users and id's of "privileges" and "roles".
herman_tho
Member
196 Points
126 Posts
Web Api with Multiple Post in one Controller
Jun 19, 2012 12:56 PM|LINK
Hi All,
I have 2 post method in 1 controller.
[HttpPost] public string Hello(string msg) { return msg; } [HttpPost] public string HelloAgain(string msg) { return msg; }I have this error, when trying to call the api "Multiple actions were found that match the request", Can anyone tell me how to solved this one
/api/Msg/Hello
C
BrockAllen
All-Star
27434 Points
4891 Posts
MVP
Re: Web Api with Multiple Post in one Controller
Jun 19, 2012 01:12 PM|LINK
Don't put two POST methods in one controller :)
Think about your HTTP request -- how will the runtime (with the default routes) distinguish which action method to invoke? Routing (and thus the URL) does not contain the action name. If you want this, then define a custom route with the action name in the URL, but that goes somewhat counter to the design of WebAPI and action method mapping based upon the HTTP method.
DevelopMentor | http://www.develop.com
thinktecture | http://www.thinktecture.com/
james-world
Member
103 Points
50 Posts
Re: Web Api with Multiple Post in one Controller
Jun 19, 2012 01:56 PM|LINK
You're right that the Web API project templates steer you down the route of RESTful controllers... but I'm not sure there is anything wrong per se with writing more RPC style APIs. Sometimes its the right thing to do.
BrockAllen
All-Star
27434 Points
4891 Posts
MVP
Re: Web Api with Multiple Post in one Controller
Jun 19, 2012 02:42 PM|LINK
Well, I don't want to get into a philosophical debate on how to use the framework. I was simply pointing out that the way the plumbing works by default is to prefer only one of each HTTP method per API controller. You can circumvent this by augmenting the routing table.
DevelopMentor | http://www.develop.com
thinktecture | http://www.thinktecture.com/
MikeWasson
Member
486 Points
78 Posts
Microsoft
Re: Web Api with Multiple Post in one Controller
Jun 19, 2012 03:43 PM|LINK
It depends what you want your URIs to look like.
If you want these URIs:
/api/Msg/Hello
/api/Msg/HelloAgain
... then you are including the action name in the URI, so you need to include {action} in your route template:
"api/{controller}/{action}/{id}"
See http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api
- Mike
herman_tho
Member
196 Points
126 Posts
Re: Web Api with Multiple Post in one Controller
Jun 21, 2012 01:37 PM|LINK
Hi Mike,
I have been follow all the way others ppl tutorial but it's get stuck.
RouteConfig
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); }Controller
public class ValuesController : ApiController { public Msg Hello(Msg model) { return model; } public Msg HelloAgain(Msg model) { return model; } } public class Msg { public string msgContent { get; set; } }Fiddler Post it's return me this
MikeWasson
Member
486 Points
78 Posts
Microsoft
Re: Web Api with Multiple Post in one Controller
Jun 21, 2012 06:07 PM|LINK
Yes -- if you want to support action-based routing (that is, the action name is part of the URI), then you need to update your route to:
"api/{controller}/{action}/{id}"
- Mike
horaciotg
Member
115 Points
44 Posts
Re: Web Api with Multiple Post in one Controller
Feb 25, 2013 02:27 PM|LINK
Hi,
I have a similar situation.
My Users Controller:
public User GetUser(int id) {
return repository.GetUserByUserID(id);
}
public User GetUser(string email) {
return repository.GetUserByEmail(email);
}
[ActionName("privileges")]
public IEnumerable<Privilege> GetPrivileges(int userID) {
return repository.GetPrivilegesByUserID(userID);
}
[ActionName("roles")]
public IEnumerable<Rol> GetRoles(int userID) {
return repository.GetRolesByUserID(userID);
}
As you can see I added AcctionName to GetPrivileges and GetRoles, i have 4 URI calls:
1. http://localhost/MySite/api/users/1 WORKS FINE.
2. http://localhost/MySite/api/users?email=myemail@mail.com WORKSFINE
3. http://localhost/MySite/api/users/privileges?userID=1 FAILS: Multiple actions were found that match the request
4. http://localhost/MySite/api/users/roles?userID=1 FAILS: Multiple actions were found that match the request
Notice that last 2 calls refers to the actions Privileges and Roles
My routes on WebApiConfig:
config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } );
config.Routes.MapHttpRoute( name: "ActionApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional } );
What am I doing wrong?
Why 3 and 4 fails?
I'll apreciate your help
james-world
Member
103 Points
50 Posts
Re: Web Api with Multiple Post in one Controller
Feb 25, 2013 06:41 PM|LINK
Your example URIs are both matching each other. Look more carefully at the rule. The query string is not part of the route. They are matching api/{controller}/{id} with a controller of users and id's of "privileges" and "roles".
To see this try http://localhost/MySite/api/users/privileges/1 - that should match your action route.
horaciotg
Member
115 Points
44 Posts
Re: Web Api with Multiple Post in one Controller
Feb 25, 2013 08:43 PM|LINK
James,
Thanks for your reply.
I tried this http://localhost/MySite/api/users/privileges/1 and try http://localhost/MySite/api/users/roles/1 , I got these errors in both cases:
No HTTP resource was found that matches the request .
No action was found on the controller Users that matches the request.
Thanks