2

在我的控制器 UserApiController 中,我具有以下功能:

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

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

在我的控制器 SalesApiController 中,我具有以下功能:

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

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

在 web api 配置中,我可以像这样映射:

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

它适用于 UserApiController.GetUsers,因为函数签名仅与 GetUsers 匹配。

现在,问题:

1.如何定义路由以处理具有相同参数数量的不同功能(在相同或不同控制器内)

2.如何定义路由以处理具有不同参数数量的不同功能(如果可能,在相同或不同控制器中)

4

2 回答 2

3

1.如何定义路由以处理具有相同参数数量的不同功能(在相同或不同控制器内)

这里有几种解决方案。

  • 使用多条路线。以您的 UserApiController 为例,很难有一个路由与 2 个动作一起使用,其中它们具有不同的参数名称。我建议添加以下两条路线:

        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" });
    
  • 按照 danludwig 的建议使用查询字符串参数。这样,您只需要一条路线:

        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.如何定义路由以处理具有不同参数数量的不同功能(如果可能,在相同或不同控制器中)

  • 同样,定义多条路线:

        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}");
    
  • 改用查询字符串参数并且只有一个路由——即上面的'DefaultApiOnlyRoute'。

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

希望这可以帮助。

于 2012-10-03T20:23:22.980 回答
2

你可以创建一个像这样的属性,然后用这个属性装饰你的动作。您仍然需要创建一个与您所做的匹配参数数量的路由一样的路由。

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

我希望它有所帮助。

于 2012-10-03T17:37:33.290 回答