Kestrel 和 ASP.NET Core MVC 使用自定義基本路徑
如何將您的應用程序安裝在不同的基本路徑上?
例如,我的控制器的路由是 /api/keywords,但是在執行 Web 伺服器時,我希望基本路徑是 /development,所以我的控制器路由是 /development/api/keywords。我寧願不必修改我的控制器。在舊的 Web API 版本中,您可以在不同的路徑中安裝 OWIN 應用程序,所以我正在尋找類似的東西。
有一種名為 UsePathBase 的新方法可以輕鬆完成此操作。 https://github.com/aspnet/HttpAbstractions/blob/bfa183747f6fb528087554c3d6ec58ef05f1c10a/src/Microsoft.AspNetCore.Http.Abstractions/Extensions/UsePathBaseExtensions.cs
您可以在此處查看原始的精彩文章
首先創建一個繼承自
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)); } }現在要使用它,首先非常常見,將您的環境保存在 Startup 類的屬性中
private IHostingEnvironment _env; public Startup(IHostingEnvironment env) { _env = env; }然後你需要做的就是呼叫你的靜態擴展類
public void ConfigureServices(IServiceCollection services) { services.AddMvc(options => { options.UseEnvironmentPrefix(new RouteAttribute(_env.EnvironmentName)); }); }但是還有最後一件事需要關心。無論您有什麼客戶端使用您的 API,您當然不想更改您發送的 HTTP 請求的所有 URL。所以訣竅是創建一個中間件,它將修改
Path您的請求以包含您的環境名稱。(來源)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); } }你
ConfigureServices在Startup課堂上的方法變成了public void ConfigureServices(IServiceCollection services) { app.UseMiddleware<EnvironmentUrlRewritingMiddleware>(); services.AddMvc(options => { options.UseEnvironmentPrefix(new RouteAttribute(_env.EnvironmentName)); }); }唯一的缺點是它不會更改您的 URL,因此如果您使用瀏覽器訪問 API,您將看不到包含您的環境的 URL。
response.Redirect即使原始請求是 POST,也始終發送 GET 請求。我還沒有找到反映 URL 路徑的最終解決方案。