在查询字符串上匹配路由

时间:2016-08-24 18:17:08

标签: routing asp.net-core-mvc asp.net-core-1.0

我正在将旧的web api应用程序转换为mvc 6 / .net核心,我遇到了一个无法解决的问题。在web api中,您可以定义映射到多个操作的单个路由,并根据查询字符串调用正确的操作。例如:

routes.MapHttpRoute(
            name: "Foo",
            routeTemplate: GetRoute("api/Foo"),
            defaults: new
            {
                controller = "Foo",
                action = "Bar",
                name = "foobar"
            }
        );
public class Foo : ApiController
{
    [AcceptVerbs("GET")]
    public Task<HttpResponseMessage> Bar(int id)

    {
        //process request
    }

    [AcceptVerbs("GET")]
    public Task<HttpResponseMessage> Bar(string message)

    {
        //process request
    }
}

foo / bar?id = 1和foo / bar?message =某些消息将被路由到正确的方法。这不适用于mvc 6.我尝试使用Microsoft.AspNetCore.Mvc.WebApiCompatShim,但它不起作用,至少不使用属性路由。除了使用所有可能的参数创建单个操作然后进行空检查之外,还有其他选项吗?遗憾的是,更改路由不是一种选择,因为客户端应用程序当前正在使用它们。

2 个答案:

答案 0 :(得分:0)

您可以使用内联约束来指定要使用的正确路由。 这是一个有效的例子

[Route("api/[controller]")]
public class FooController : Controller
{

    // GET api/foo/bar/123
    [HttpGet("{id:int}")]
    public int Bar(int id)
    {
        return id;
    }

    // GET api/foo/bar/abc
    [HttpGet("{message:alpha}")]
    public string Bar(string message)
    {
        return $"String value \"{message}\"";
    }
}

答案 1 :(得分:0)

这可能对你的问题有好处

中间件:

public class RewriteUrl
{
    RequestDelegate _next;
    public RewriteUrl(RequestDelegate next )
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        var path = context.Request.Path.ToUriComponent();

        if (string.Equals(path, "/api/foo", StringComparison.OrdinalIgnoreCase))
        {
            var querystring = context.Request.QueryString.ToUriComponent();
            //remove ? at the top of string
            querystring = querystring.Substring(1);
            var querystringVector = querystring.Split('&');
            for(var i=0; i<querystringVector.Length; i++)
            {
                var querystringValue = querystringVector[i];
                var querystringValueVector = querystringValue.Split('=');
                if ( querystringValueVector[0].Equals("id", StringComparison.OrdinalIgnoreCase) ||
                    querystringValueVector[0].Equals("message", StringComparison.OrdinalIgnoreCase))
                {
                    context.Request.Path = "/Api/foo/bar/" + querystringValueVector[1];
                }
            }
        }

        await _next.Invoke(context);
    }
}

public static class RewriteUrlExtensions
{
    public static IApplicationBuilder UseRewriteUrl(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<RewriteUrl>();
    }
}

进入你的初创班:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        app.UseRewriteUrl();

        app.UseMvc();
    }

你的控制器:

[Route("api/[controller]")]
public class FooController : Controller
{

    // GET api/foo/bar/123
    [HttpGet("bar/{id:int}")]
    public int Bar(int id)
    {
        return id;
    }

    // GET api/foo/bar/abc
    [HttpGet("bar/{message:alpha}")]
    public string Bar(string message)
    {
        return $"String value \"{message}\"";
    }
}