#asp.net-core #url-rewriting #web-config
#asp.net-core #url-перезапись #веб-конфигурация #web-config
Вопрос:
У меня есть следующий Web.Config, который отлично работает для IIS. Однако он не работает для самостоятельного размещения, как в службе Windows.
<system.webServer>
<rewrite>
<rules>
<rule name="Angular Routes" stopProcessing="true">
<match url="./*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
</rule>
</rules>
</rewrite>
</system.webServer>
Чтобы пользовательский интерфейс не обрабатывал /api как часть URL-адреса html.
Однако я разместил это приложение в службе Windows, и этот файл web.config больше не работает. index.html файл возвращается.
Есть ли способ, которым я мог бы добавить это правило в .net core, чтобы это же правило применялось, когда я размещаю его в службе Windows, а не IIS.
Класс запуска:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "publish/ClientApp/dist";
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
if (!env.IsDevelopment())
{
app.UseSpaStaticFiles();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}
Класс программы:
Добавлена следующая логика для запуска в качестве службы Windows
public static void Main(string[] args)
{
//Check for the Debugger is attached or not if attached then run the application in IIS or IISExpress
var isService = false;
//when the service start we need to pass the --service parameter while running the .exe
if (Debugger.IsAttached == false amp;amp; args.Contains("--service"))
{
isService = true;
}
if (isService)
{
//Get the Content Root Directory
var pathToContentRoot = Directory.GetCurrentDirectory();
string ConfigurationFile = "appsettings.json"; //Configuration file.
string portNo = "5003"; //Port
var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
pathToContentRoot = Path.GetDirectoryName(pathToExe);
//Get the json file and read the service port no if available in the json file.
string AppJsonFilePath = Path.Combine(pathToContentRoot, ConfigurationFile);
if (File.Exists(AppJsonFilePath))
{
using (StreamReader sr = new StreamReader(AppJsonFilePath))
{
string jsonData = sr.ReadToEnd();
JObject jObject = JObject.Parse(jsonData);
if (jObject["ServicePort"] != null)
portNo = jObject["ServicePort"].ToString();
}
}
var host = WebHost.CreateDefaultBuilder(args)
.UseContentRoot(pathToContentRoot)
.UseStartup<Startup>()
.UseUrls("http://localhost:" portNo)
.Build();
host.RunAsService();
}
else
{
CreateHostBuilder(args).Build().Run();
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
Комментарии:
1. Вы пробовали это? var rewrite = new RewriteOptions() .AddRewrite(«api / values», «api /default», true); app.UseRewriter(перезаписать);
Ответ №1:
ASP.NET Промежуточное программное обеспечение для перезаписи основных URL-адресов было создано специально для этой цели. Согласно документации: используйте промежуточное ПО для перезаписи URL, если вы не можете использовать следующие подходы:
- Модуль перезаписи URL с IIS на Windows Server
- Модуль Apache mod_rewrite на сервере Apache
- Перезапись URL-адреса в Nginx
Первым шагом является установление правил перезаписи и перенаправления URL-адресов путем создания экземпляра класса RewriteOptions с методами расширения для любого из ваших правил перезаписи. Пример этого определен ниже:
public void Configure(IApplicationBuilder app)
{
using (StreamReader apacheModRewriteStreamReader =
File.OpenText("ApacheModRewrite.txt"))
using (StreamReader iisUrlRewriteStreamReader =
File.OpenText("IISUrlRewrite.xml"))
{
var options = new RewriteOptions()
.AddRedirect("redirect-rule/(.*)", "redirected/$1")
.AddRewrite(@"^rewrite-rule/(d )/(d )", "rewritten?var1=$1amp;var2=$2",
skipRemainingRules: true)
.AddApacheModRewrite(apacheModRewriteStreamReader)
.AddIISUrlRewrite(iisUrlRewriteStreamReader)
.Add(MethodRules.RedirectXmlFileRequests)
.Add(MethodRules.RewriteTextFileRequests)
.Add(new RedirectImageRequests(".png", "/png-images"))
.Add(new RedirectImageRequests(".jpg", "/jpg-images"));
app.UseRewriter(options);
}
app.UseStaticFiles();
app.Run(context => context.Response.WriteAsync(
$"Rewritten or Redirected Url: "
$"{context.Request.Path context.Request.QueryString}"));
}
Сопоставление регулярных выражений
Если вы специально хотите использовать перезаписи с использованием сопоставления регулярных выражений, вы можете использовать AddRedirect для перенаправления запросов. Первый параметр содержит ваше регулярное выражение для сопоставления по пути к входящему URL. Второй параметр — это строка замены. Третий параметр, если он присутствует, указывает код состояния. Если вы не укажете код состояния, по умолчанию код состояния равен 302 — Найден, что указывает на то, что ресурс временно перемещен или заменен.
Пример:
AddRewrite(@"^rewrite-rule/(d )/(d )", "rewritten?var1=$1amp;var2=$2",
skipRemainingRules: true)
Для вашего конкретного запроса
Для вашего конкретного запроса вы должны использовать что-то похожее на следующее в вашем методе Configure:
var options = new RewriteOptions().AddRewrite(@"/(api)/(.*)", "/$2",true);
Имейте в виду, что вам может потребоваться настроить значения регулярных выражений в соответствии с конкретной целью в зависимости от конфигурации вашего приложения.
app.UseRewriter(перезапись);
Ответ №2:
Вам нужно запустить с RunAsCustomService
public static class WebHostServiceExtensions
{
public static void RunAsCustomService(this IWebHost host)
{
var webHostService = new CustomWebHostService(host);
ServiceBase.Run(webHostService);
}
}
Возможно, здесь может помочь вашей проблеме.