2

I have been struggling with this problems for days. I have a controller that need to have multiple GET and POST methods. Somehow I managed to achieve multiple GET methods in the controller. At that time there was only one POST method. Everything was running fine until I introduced one more POST method. Whenever I use POST method from client side using ExtJS, only the first POST method gets called. Here are the methods in my controller:

[AllowAnonymous]
[ActionName("userlist")]
[HttpGet]
public List<MyApp.Entity.Models.usermaster> Get(bool isActive)
{
//My code
}

[AllowAnonymous]
[ActionName("alluserlist")]
[HttpGet]
public List<MyApp.Entity.Models.usermaster> Get()
{
//My code
}

[AllowAnonymous]
[ActionName("updateuser")]
[HttpPost]
public string UpdateUser(JObject userData)
{
//My code
}


[AllowAnonymous]
[ActionName("adduser")]
[HttpPost]
public string AddUser(JObject newUserData)
{
//My code
}

I also have two route config files. The first one has the following configuration:

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}

Another file has the following configuration:

public static void Register(HttpConfiguration config)
{
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute(
name: "ControllersWithAction",
routeTemplate: "api/{controller}/{action}");

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

This is how the ajax call is made to the api:

Ext.Ajax.request({
     url: 'localhost/myapp/api/users/adduser',
     mode: 'POST',
     params: {
              userName: 'user',
              password: 'password'
             },
     success: function (resp) {
              var respObj = Ext.decode(resp.responseText);
                  if (respObj == 'added') {
                  Ext.Msg.alert('Success', 'User added.');
                  }
                                        else {
                                            Ext.Msg.alert('Error', respObj);
                                        }
                                    },
                                    failure: function (resp) {
                                        Ext.Msg.alert('Error', 'There was an error.');
                                    }
                                });

Can anyone point out the mistake? Alternatively, any example with multiple GET and POST methods in side one controller with route config would be very helpful.

user1640256
  • 1,691
  • 7
  • 25
  • 48
  • 1
    How are you calling them? – L-Four Mar 27 '14 at 10:07
  • For get method I use 'localhost/myapp/api/users/userlist/true' & localhost/myapp/api/users/alluserlist' that works fine. For both the POST methods I am using only 'localhost/myapp/api/users' with different parameters. – user1640256 Mar 27 '14 at 10:15
  • But how are you calling them? How do you specify in the request it's a POST or GET? – L-Four Mar 27 '14 at 10:22
  • I am using ExtJS. While making an ajax call to a URL you have to specify method type. Here is an example: proxy: { type: 'ajax', url: 'localhost/myapp/api/users/userlist/true', method: 'GET' } – user1640256 Mar 27 '14 at 10:27
  • How are you sending which POST method to be used ? – Yasser Shaikh Mar 27 '14 at 10:47
  • @user1640256 what is the endpoint that you are trying to hit in both POST requests? It also catches my attention, that you have added an ActionName attribute to the GET methods and not on the POST ones. Btw it shouldn't matter how many get/post/put/whatever methods you have in your controller. It should work regardless of the amount of actions. – Vasil Dininski Mar 27 '14 at 11:05
  • See my updated code in the question. I use action name with the URL. – user1640256 Mar 27 '14 at 11:06
  • @Vasil : See my updated code. I use action name with the URL – user1640256 Mar 27 '14 at 11:07

3 Answers3

4

why don't you use PUT method for UpdateUser ?

[AllowAnonymous]
[HttpPut]
public string UpdateUser(JObject userData)
{
   //My code
}

update:

you can use multiple POST but then you should either use ActionNames that works but is not restful or stop using Complex Types as parameters. because Web API ignores Complex Types when it tries to select most appropriate Action . check these :

Multiple actions for the same HttpVerb

http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection

Community
  • 1
  • 1
mohsen dorparasti
  • 8,107
  • 7
  • 41
  • 61
0

You could try this

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "ApiById",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional },
            constraints: new { id = @"^[0-9]+$" }
        );

        config.Routes.MapHttpRoute(
            name: "ApiByName",
            routeTemplate: "api/{controller}/{action}/{name}",
            defaults: null,
            constraints: new { name = @"^[a-z]+$" }
        );

        config.Routes.MapHttpRoute(
            name: "ApiByAction",
            routeTemplate: "api/{controller}/{action}",
            defaults: new { action = "Get" }
        );
    }
}
Yasser Shaikh
  • 46,934
  • 46
  • 204
  • 281
-3

you can use ActionName for your method as well

[AllowAnonymous]
[HttpPost]
[ActionName("userlist")]
public string UpdateUser(JObject userData)
{
//My code
}


[AllowAnonymous]
[HttpPost]
[ActionName("alluserlist")]
public string AddUser(JObject newUserData)
{
//My code
}

Also, you have to use ActionName in your URL for API, when you call your post method. Make sure your route Config have {action} in WebApiConfig.

for custom binding in web API you can refer following link https://blogs.msdn.microsoft.com/jmstall/2012/04/16/how-webapi-does-parameter-binding/

Subhash Rao
  • 335
  • 2
  • 7