2016-08-24 88 views
1

我正在将旧版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,但它不起作用,至少没有使用属性路由。除了用所有可能的参数创建单个动作,然后进行空检查之外,是否还有其他选择?不幸的是,改变路线不是一种选择,因为它们目前正在被客户端应用程序使用。

回答

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}\""; 
    } 
} 
+0

这将工作,但我不能使用api/foo/bar/abc我需要使用api/foo?message = abc和api/foo?id = 123 – cdaq

+0

您可以使用重写url引擎来转换来自api的请求/ foo?message = abc to api/foo/bar/abc和api/foo?id = 123 to api/boo/bar/123。 –

+0

这会工作!你能指出我有哪些资源可以说明如何做到这一点?我不熟悉重写URL引擎。 – cdaq

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}\""; 
    } 
} 
+0

有趣,谢谢。我会试试这个方法。 – cdaq