unruledboy
unruledboy

Reputation: 2342

asp.net mvc web api same controller different function parameters

In my controller UserApiController, I have the following functions:

public object GetUsers(string CountryID, string StateID)
{
   //biz
}

public object GetPositions(int CompanyID, int DepartmentID)
{
   //biz
}

In my controller SalesApiController, I have the following functions:

public object GetOrders(string CountryID, int CompanyID)
{
   //biz
}

public object GetProducts(string CountrID, string StateID, int CompanyID)
{
   //biz
}

in the web api config, I can map like this:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{action}/{CountryID}/{StateID}",
    defaults: new {  }

and it works for UserApiController.GetUsers as the function signature only matches with GetUsers.

now, questions:

1.how to define a route to handle different functions with same amount of parameters (either within same or different controller)

2.how to define a route to handle different functions with different amount of parameters (either within same or different controller, if possible)

Upvotes: 2

Views: 3415

Answers (2)

André Scartezini
André Scartezini

Reputation: 236

You can create an attribute like this one and then decorate your actions with this attribute. You still need to create a route like the one you did that matches the number of parameters.

public class SomeAttribute : ActionFilterAttribute
{
  public override void OnActionExecuting(ActionExecutingContext filterContext)
  {
    for(int i = 0; i <= filterContext.ActionParameters.Count; i++)
    {
      // i + 2 is to not consider controller and action parameters
      filterContext.ActionParameters[filterContext.ActionParameters.ElementAt(i).Key] = 
        Convert.ChangeType(
          filterContext.Controller.ControllerContext.RouteData.Values.ElementAt(i + 2).Value, 
          filterContext.ActionDescriptor.GetParameters()[i].ParameterType
        );
      }
   }
}

I hope it helps.

Upvotes: 2

Maggie Ying
Maggie Ying

Reputation: 10185

1.how to define a route to handle different functions with same amount of parameters (either within same or different controller)

There are several solutions here.

  • Use multiple routes. Take your UserApiController as an example, it is hard to have one route that works with the 2 actions, in which they have different parameter names. I would suggest add the following 2 routes:

        config.Routes.MapHttpRoute(
            name: "DefaultApi-UserApiGetUsers",
            routeTemplate: "api/{controller}/GetUsers/{CountryID}/{StateID}",
            defaults: new { action = "GetUsers" });
    
        config.Routes.MapHttpRoute(
            name: "DefaultApi-UserApiGetPositions",
            routeTemplate: "api/{controller}/GetPositions/{CompanyID}/{DepartmentID}",
            defaults: new { action = "GetPositions" });
    
  • Use query string parameters as danludwig has suggested. This way, you only need this one route:

        config.Routes.MapHttpRoute(
            name: "DefaultApiOnlyRoute",
            routeTemplate: "api/{controller}/{action}");
    
    1. api/UserApi/GetUsers?CountryID=USA&StateID=WA
    2. api/UserApi/GetPositions?CompanyID=123&DepartmentID=456

2.how to define a route to handle different functions with different amount of parameters (either within same or different controller, if possible)

  • Again, define multiple routes:

        config.Routes.MapHttpRoute(
            name: "DefaultApi-SalesApi2Params",
            routeTemplate: "api/{controller}/{action}/{CountryID}/{CompanyID}");
    
        config.Routes.MapHttpRoute(
            name: "DefaultApi-SalesApi3Params",
            routeTemplate: "api/{controller}/{action}/{CountryID}/{StateID}/{CompanyID}");
    
  • Use query string parameters instead and have only one route -- i.e. the 'DefaultApiOnlyRoute' from above.

    1. api/SalesApi/GetOrders?CountryID=USA&CompanyID=123
    2. api/SalesApi/GetProducts?CountryID=USA&StateID=WA&CompanyID=123

Hope this helps.

Upvotes: 3

Related Questions