Приложение ASP.NET Core создается с использованием шаблона проекта Visual Studion 2019 ASP.NET Core Application.
Его _layout.cshtml содержит пути к файлам css относительно корневого каталога приложения:
<head>
<meta charset = "utf-8" />
<meta name = "viewport" content = "width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - WebApplication1</title>
<link rel = "stylesheet" href = "~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel = "stylesheet" href = "~/css/site.css" />
</head>
Это приложение работает в Debian Linux 10 с apache в виртуальном каталоге nettest с использованием инструкций из https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-apache
Модули Apache mod_proxy и header предназначены для пересылки HTTPS-запросов на сервер Kestrel. Файл конфигурации Apache:
<Location "/nettest">
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
ProxyPreserveHost On
ProxyPass http://127.0.0.1:5000/
ProxyPassReverse http://127.0.0.1:5000/
</location>
Приложение не находит файлы css. Источник представления браузера показывает, что абсолютные пути отображаются в html-коде:
<head>
<meta charset = "utf-8" />
<meta name = "viewport" content = "width=device-width, initial-scale=1.0" />
<title>Home Page - WebApplication1</title>
<link rel = "stylesheet" href = "/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel = "stylesheet" href = "/css/site.css" />
</head>
как заставить отображать правильные URL-адреса, экв. относительный из текущей папки, например
библиотека/бутстрап/расстояние/CSS/bootstrap.min.css
или абсолютный из виртуального каталога приложения:
/nettest/lib/bootstrap/dist/css/bootstrap.min.css
** Обновлять **
После изменения порядка файлы css находятся. Однако ссылка на конфиденциальность в шаблоне примера приложения по-прежнему не работает.
Шаблон ASP.NET содержит:
<div class = "navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class = "navbar-nav flex-grow-1">
<li class = "nav-item">
<a class = "nav-link text-dark" asp-area = "" asp-controller = "Home" asp-action = "Index">Home</a>
</li>
<li class = "nav-item">
<a class = "nav-link text-dark" asp-area = "" asp-controller = "Home" asp-action = "Privacy">Privacy</a>
</li>
</ul>
</div>
В браузере отображается как
<div class = "navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class = "navbar-nav flex-grow-1">
<li class = "nav-item">
<a class = "nav-link text-dark" href = "/nettest">Home</a>
</li>
<li class = "nav-item">
<a class = "nav-link text-dark" href = "/nettest/Home/Privacy">Privacy</a>
</li>
</ul>
</div>
Ссылка на главную работает, но ссылка на конфиденциальность выдает ошибку 404.
В шаблоне определен HomeController:
public IActionResult Privacy()
{
return View();
}
Это работает, когда приложение работает под Visual Studio. Как заставить работать личную ссылку, когда приложение работает в виртуальном каталоге Apache?
Метод настройки:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-apache?view=aspnetcore-2.2
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseAuthentication();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
// origoli: app.UseStaticFiles();
// https://stackoverflow.com/questions/46593999/how-to-host-a-asp-net-core-application-under-a-sub-folder
// https://forums.asp.net/post/6327484.aspx
// because the middleware
//app.UsePathBase("/nettest");
// strips the /nettest from the pipeline, the static file handler middleware needs to come first:
app.UseStaticFiles(new StaticFileOptions
{
RequestPath = new PathString("/nettest")
});
app.UsePathBase("/nettest");
// in asp.net core, you control the order of middleware and must get it correct.
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
Проблема может быть связана с порядком, который вы определили UseStaticFiles и UseAuthentication. Переместите UseStaticFiles выше UseAuthentication. Лучшим подходом является использование самого Apache для рендеринга статических файлов.
Удалите косую черту после ProxyPass и ProxyPassReverse.
ProxyPass http://127.0.0.1:5000/nettest
(без косой черты) сработало. Спасибо.
После изменения порядка полей css найдены, но вызов контроллера конфиденциальности все еще вызывает ошибку 404. я обновил вопрос