0

I'm not a .NET developer but gotta provide a sample ASP.NET Core Web App (Model-View-Controller) to a client. But I have a problem when deploying it onto Kubernetes.

For example, when I click Privacy button, I get 404 errors. enter image description here

//ex.
// root
www.example.com/custom/path

// Desired
www.example.com/custom/path/Home/Privacy

// Actual - 404 error as ingress cannot route it.
www.example.com/Home/Privacy

Code

I'm using nginx-ingress for routing traffics.

The ingress looks like (using rewrite)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    //...
    // I have to use rewrite
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    //...

spec:
  ingressClassName: nginx
  rules:
    - host: www.example.com
      http:
        paths:
          - backend:
              service:
                name: dotnet-service
                port:
                  number: 8080
            path: /custom/path/?(.*)
            pathType: ImplementationSpecific

Program.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    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();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

Views/Shared/_Layout.cshtml

<!DOCTYPE html>
<html lang="en">
<head>
    @* Add below line for setting prefix for href in link tag *@
    <base href="/custom/path/">
    @* ... *@
    <link rel="stylesheet" href="lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="MVPPractice.styles.css" asp-append-version="true" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container-fluid">
                <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MVPPractice</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <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>
        </nav>
    </header>

    @* ... *@

    <script src="lib/jquery/dist/jquery.min.js"></script>
    <script src="lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="js/site.js" asp-append-version="true"></script>
    @await RenderSectionAsync("Scripts", required: false)
</body>
</html>

Traffic flow

ASP.NET program's base is root(/) not /custom/path, that's why I use nginx-ingress's rewrite. enter image description here

Current Issue

  1. Request www.example.com/custom/path/
  • Response 200
  • href of <a> is /Home/Privacy which leads to www.example.com/Home/Privacy, it is supposed to be /custom/path/Home/Privacy so that it leads to www.example.com/custom/path/Home/Privacy.
  1. Click the link <a>
  • Requests www.example.com/Home/Privacy
  • Response 404 (because nginx-ingress cannot route it)

How do I set prefix for static file responses?

5
  • Can you show us your program.cs file? You should have a line something like app.UseStaticFiles(); in there - do you? Commented Nov 25, 2024 at 15:31
  • @marc_s thx I'ved added Program.cs and _Layout.cshtml. I've got that line as I barely changed the code. Commented Nov 26, 2024 at 0:17
  • 1
    I suspect something is off with the url rewrite in the ingress. Can you see in the aspnet core logs what url is being requested from the app? Commented Nov 26, 2024 at 1:33
  • Make sure you read learn.microsoft.com/en-us/aspnet/core/host-and-deploy/… So long as your proxy sets X-Forwarded-Prefix and you configure the server to trust it, then everything should work without hard-coding anything. Commented Nov 26, 2024 at 4:31
  • @ESG No logs as nginx-ingress failed the route the request, it couldn't even reach asp.net program. The requested url need be based on root from dotnet's perspective. Commented Nov 26, 2024 at 4:32

1 Answer 1

0

You could try this below code to rewrite the url to your custom path to avoid the 404 error:

Program.cs:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();

// Configure the application to use a base path
app.UsePathBase("/custom/path"); 

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}
app.UseHttpsRedirection();

app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();

YAML:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: dotnet-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /custom/path/$1
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  ingressClassName: nginx
  rules:
    - host: www.example.com
      http:
        paths:
          - path: /custom/path/?(.*)
            pathType: ImplementationSpecific
            backend:
              service:
                name: dotnet-service
                port:
                  number: 8080

If you only would like to serve the static file you could use the RequestPath something like below:

app.UseStaticFiles(new StaticFileOptions
{
    RequestPath = "/StaticFiles"
});

If you would like entire application, including routes, controllers, and static files use the path like /custom/path use app.UsePathBase("/custom/path");

Sign up to request clarification or add additional context in comments.

1 Comment

The rewrite-target can't be changed as it is intended. Inside the container(ASP.NET), the base is root but outside the kubernetes, it's /custom/path (from user's perspective)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.