简体   繁体   中英

Multiple GET and POST methods in Web API controller

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.

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

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" }
        );
    }
}

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/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM