Как отправить действие контроллера в параметре url в Asp.net Web Api? - PullRequest
0 голосов
/ 31 августа 2018

Обычно вы называете действие контроллера следующим образом 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 голосов
/ 26 мая 2019

Спустя больше года я могу вернуться к этому вопросу и ответить на него сам. Решение, которое вы можете использовать здесь, это написать свой собственный 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

0 голосов
/ 31 августа 2018

Вы можете попробовать следующее:

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

Все станет сложнее, если вам потребуются дополнительные параметры.

...