如何在Asp.net Web Api中的url参数中发送控制器操作?

时间:2018-08-31 17:25:16

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

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

我的控制器:

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

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

2 个答案:

答案 0 :(得分: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();
    }
}

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

答案 1 :(得分:1)

一年多以后,我可以回到这个问题并自己回答。 您可以在此处使用的解决方案是编写自己的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