如何在Asp.Net WebApi中配置路由以使用操作方法名称作为查询参数?

时间:2017-08-07 09:11:25

标签: asp.net asp.net-web-api

我想基于查询字符串参数调用不同的操作方法,例如,webapi/mycontroller?action=getuser&id=10应调用mycontroller.getuser(10)操作方法,webapi/mycontroller?action=getallusers应调用mycontroller.getallusers()操作方法。我试着用以下方式编写路由:

config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "webapi/{controller}?action={action}"
            );

但是这是不允许的,visual studio给了我错误The route URL cannot start with a '/' or '~' character and it cannot contain a '?' character

1 个答案:

答案 0 :(得分:1)

所以我一起敲了一些可能有助于你开始的东西

首先使用自定义处理程序

创建一个路径
config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}",
    defaults: null,
    constraints: null,
    handler: new CustomHttpControllerDispatcher(config)
);

public class CustomHttpControllerDispatcher : HttpMessageHandler
{
    private IHttpControllerSelector _controllerSelector;
    private readonly HttpConfiguration _configuration;

    public CustomHttpControllerDispatcher(HttpConfiguration configuration)
    {
        _configuration = configuration;
    }

    public HttpConfiguration Configuration
    {
        get { return _configuration; }
    }

    private IHttpControllerSelector ControllerSelector
    {
        get
        {
            if (_controllerSelector == null)
            {
                _controllerSelector = _configuration.Services.GetHttpControllerSelector();
            }
            return _controllerSelector;
        }
    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        return SendAsyncInternal(request, cancellationToken);
    }

    private Task<HttpResponseMessage> SendAsyncInternal(HttpRequestMessage request, CancellationToken cancellationToken)
    {

        IHttpRouteData routeData = request.GetRouteData();
        Contract.Assert(routeData != null);

        HttpControllerDescriptor httpControllerDescriptor = ControllerSelector.SelectController(request);
        IHttpController httpController = httpControllerDescriptor.CreateController(request);


        foreach (var queryParam in request.GetQueryNameValuePairs())
        {
            routeData.Values.Add(queryParam.Key, queryParam.Value);
        }


        // Create context
        HttpControllerContext controllerContext = new HttpControllerContext(_configuration, routeData, request);
        controllerContext.Controller = httpController;
        controllerContext.ControllerDescriptor = httpControllerDescriptor;

        return httpController.ExecuteAsync(controllerContext, cancellationToken);
    }
}

然后设置你的方法进入控制器

public class MyController : ApiController
{
    [HttpGet]
    public IHttpActionResult GetUser([FromUri]int userId)
    {
        return Ok();
    }

    [HttpGet]
    public IHttpActionResult DoSomething([FromUri]string test)
    {
        return Ok();
    }
}

我只尝试使用GET方法,POST可能会起作用,但我还没有测试过。