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的路径。