2016-08-24 44 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