How to create urls for .NET Core application in Apache virtual directory

748 views Asked by At

ASP.NET Core application is created using Visual Studion 2019 ASP.NET Core Application project template.

Its _layout.cshtml contains css file paths relative to application root directory:

<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>

This application is running in Debian Linux 10 with apache in nettest virtual directory using instructions from https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-apache

Apache mod_proxy and header modules are user to forward https requests to kestrel server. Apache conf file:

<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>

Application does not find css files. Browser view source shows that absolute paths are rendered in html code:

<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>

how to force to render proper URLs, eq. relative from current folder like

lib/bootstrap/dist/css/bootstrap.min.css

or absolute from application virtual directory:

/nettest/lib/bootstrap/dist/css/bootstrap.min.css

** Update **

After changing order css files are found. However Privacy link in sample applicatino tempate is still not working.

ASP.NET template contains:

            <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>

In browser in appears as

           <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>

Home link works but Privacy link throws 404 error.

In template HomeController is is defined:

public IActionResult Privacy()
        {
            return View();
        }

It works when application is running under Visual Studio. How to make privary link to work when application is running in Apache virtual directory ?

Configure method:

        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?}");
        });
    }
1

There are 1 answers

3
Vijay On BEST ANSWER

Issue might be with the order you defined UseStaticFiles and UseAuthentication. Move UseStaticFiles above UseAuthentication. A better approach is to use Apache itself to render the static files.