【问题标题】:How to send controller action in url parameter in Asp.net Web Api?如何在 Asp.net Web Api 的 url 参数中发送控制器操作?
【发布时间】:2019-02-06 18:25:04
【问题描述】:

通常您会调用控制器的操作,例如 http://hostname/MyController/MyAction 我要求我的 Web Api 具有这样的路由: http://hostname/MyController?action=MyAction,即在url参数中传递action。

我的控制器:

public class MyController : ApiController
{
    [HttpGet]
    [Route("WHAT SHOULD BE HERE??")]
    public IHttpActionResult MyAction()
    {
        // some code 
    }
}

有什么想法可以编写这样的路由吗?

【问题讨论】:

    标签: c# asp.net asp.net-web-api asp.net-web-api-routing


    【解决方案1】:

    您可以尝试以下方法:

    public class MyController : ApiController
    {
        [HttpGet]
        [Route("MyController")]
        public IHttpActionResult MyInnerController(String action)
        {
            switch(action)
            {
                case "MyAction":
                    return MyAction();
            }
    
            return BadRequest("Invalid action: " + action);
        }
    
        public IHttpActionResult MyAction()
        {
            return Ok();
        }
    }
    

    如果您需要其他参数,事情会变得更加复杂。

    【讨论】:

      【解决方案2】:

      一年多后,我可以回过头来自己回答这个问题。 您可以在此处使用的解决方案是编写自己的 ActionSelector - 这是 Web Api 框架用于选择操作的类,默认情况下它使用 System.Web.Http.Controllers.ApiControllerActionSelector,您可以覆盖它。

      假设您的控制器如下所示:

      public class MyController : ApiController
      {
          [HttpGet]
          public IHttpActionResult MyAction()
          {
              // some code 
          }
      }
      

      然后你可以像这样创建自己的动作选择器(代码可能会改进,我写得很快):

      public class QueryParameterActionSelector : ApiControllerActionSelector
      {
          public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
          {
              var mapping = GetActionMapping(controllerContext.ControllerDescriptor);
      
              var parameters = controllerContext.Request.GetQueryNameValuePairs();
              foreach (var parameter in parameters)
              {
                  if (parameter.Key == "action")
                  {
                      if (mapping.Contains(parameter.Value))
                      {
                          // Provided that all of your actions have unique names.
                          // Otherwise mapping[parameter.Value] will return multiple actions and you will have to match by the method parameters.
                          return mapping[parameter.Value].First();
                      }
                  }
              }
      
              return null;
          }
      }
      

      最后你必须在WebApiConfig.Register 方法中注册这个动作选择器。它看起来像这样:

      public static class WebApiConfig
      {
          public static void Register(HttpConfiguration config)
          {
              config.MapHttpAttributeRoutes();
      
              config.Routes.MapHttpRoute(
                  name: "DefaultApi",
                  routeTemplate: "api/{controller}"
              );
      
              config.Services.Replace(typeof(IHttpActionSelector), new QueryParameterActionSelector());
          }
      }
      

      现在您可以像这样调用您的操作http://hostname/controller?action=MyAction

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-06
        • 1970-01-01
        • 2017-10-31
        相关资源
        最近更新 更多