1

如何將您的應用安裝在不同的基本路徑上?Kestrel和ASP.NET Core MVC使用自定義基本路徑

例如,我的控制器的路由是/ api/keywords,但是當運行web服務器時我希望basepath是/ development,所以我的控制器路由是/ development/api/keywords。我寧願不必修改我的控制器。在舊的Web API版本中,您可以在不同的路徑中安裝OWIN應用程序,所以我期望做類似的事情。

回答

0

在此請看:

public class Program 
{ 
    public static void Main(string[] args) 
    { 
     var contentRoot = Directory.GetCurrentDirectory(); 

     var config = new ConfigurationBuilder() 
      .SetBasePath(contentRoot) 
      .Build(); 

     var hostBuilder = new WebHostBuilder() 

      //Server 
      .UseKestrel() 

      //Content root - in this example it will be our current directory 
      .UseContentRoot(contentRoot) 

      //Web root - by the default it's wwwroot but here is the place where you can change it 
      .UseWebRoot("wwwroot") 

      //Startup 
      .UseStartup<Startup>(); 


     var host = hostBuilder.Build(); 

     host.Run(); 
    } 
} 

有兩種擴展方法 - UseWebRoot()和UseContentRoot() - 可用於配置網絡和內容的根。

0

您可以查看原始大文章here

首先創建一個從IApplicationModelConvention接口繼承

public class EnvironmentRouteConvention : IApplicationModelConvention 
{ 
    private readonly AttributeRouteModel _centralPrefix; 

    public EnvironmentRouteConvention(IRouteTemplateProvider routeTemplateProvider) 
    { 
     _centralPrefix = new AttributeRouteModel(routeTemplateProvider); 
    } 

    public void Apply(ApplicationModel application) 
    { 
     foreach (var controller in application.Controllers) 
     { 
      var matchedSelectors = controller.Selectors.Where(x => x.AttributeRouteModel != null).ToList(); 
      if (matchedSelectors.Any()) 
      { 
       foreach (var selectorModel in matchedSelectors) 
       { 
        //This will apply only to your API controllers. You may change that depending of your needs 
        if (selectorModel.AttributeRouteModel.Template.StartsWith("api")) 
        { 
         selectorModel.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(_centralPrefix, selectorModel.AttributeRouteModel); 
        } 
       } 
      } 
     } 
    } 

然後創建一個類只是爲了更方便和更清潔的使用目的的一類。

public static class MvcOptionsExtensions 
{ 
    public static void UseEnvironmentPrefix(this MvcOptions opts, IRouteTemplateProvider routeAttribute) 
    { 
     opts.Conventions.Insert(0, new EnvironmentRouteConvention(routeAttribute)); 
    } 
} 

我們使用它,第一個很常見的,節省您的環境中您的啓動類的屬性

private IHostingEnvironment _env; 

public Startup(IHostingEnvironment env) 
{ 
    _env = env; 
} 

然後所有你需要做的就是打電話給你的靜態extention類

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddMvc(options => 
    { 
     options.UseEnvironmentPrefix(new RouteAttribute(_env.EnvironmentName)); 
    }); 
} 

但還有最後一件事值得關注。無論您擁有哪種客戶端使用您的API,您當然不希望更改您發送的HTTP請求的所有URL。所以訣竅是創建一箇中間件,它將修改您的請求的Path以包含您的環境名稱。 (source

public class EnvironmentUrlRewritingMiddleware 
{ 
    private readonly RequestDelegate _next; 

    public EnvironmentUrlRewritingMiddleware(RequestDelegate next) 
    { 
     _next = next; 
    } 

    public async Task Invoke(HttpContext context, IHostingEnvironment env) 
    { 
     var path = context.Request.Path.ToUriComponent(); 
     //Again this depends of your need, whether to activate this to your API controllers only or not 
     if (!path.StartsWith("/" + env.EnvironmentName) && path.StartsWith("/api")) 
     { 
      var newPath = context.Request.Path.ToString().Insert(0, "/" + env.EnvironmentName); 
      context.Request.Path = newPath; 
     } 
     await _next.Invoke(context); 
    } 
} 
Startup

和你ConfigureServices方法變得

public void ConfigureServices(IServiceCollection services) 
{ 
    app.UseMiddleware<EnvironmentUrlRewritingMiddleware>(); 
    services.AddMvc(options => 
    { 
     options.UseEnvironmentPrefix(new RouteAttribute(_env.EnvironmentName)); 
    }); 
} 

唯一的缺點它不會改變你的網址,因此,如果你打你的API與您的瀏覽器,您將不會看到包含您的環境的網址。 response.Redirect總是發送GET請求,即使原始請求是POST。我還沒有找到最終的解決方案來反映URL的路徑。