如何在ASP.NET Core中实现旧.html URL重定向至无后缀页面
Hey there! Let's tackle this URL redirection issue for your ASP.NET Core project. I've got a couple of solid approaches to get those old .html URLs pointing to the new clean paths seamlessly—whether you need bulk handling or more granular control.
Approach 1: URL Rewriting Middleware (Bulk Handling)
This is the go-to method for redirecting all .html URLs at once. It uses ASP.NET Core's built-in URL Rewriting middleware, which is efficient and easy to configure.
Add the Rewrite Rules to
Program.cs
Insert the rewrite configuration right afterUseStaticFiles()and beforeUseRouting()in your request pipeline:var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); var app = builder.Build(); if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); // Configure URL rewriting for .html redirects var rewriteOptions = new RewriteOptions() // First, rewrite the request internally to match the clean path .AddRewrite(@"^(.+)\.html$", "$1", skipRemainingRules: true) // Send a 301 permanent redirect to inform browsers and search engines .AddRedirect(@"^(.+)\.html$", "$1", statusCode: StatusCodes.Status301MovedPermanently); app.UseRewriter(rewriteOptions); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();How It Works
- The regex
^(.+)\.html$captures any URL ending with.html(e.g.,/goodpage.htmlcaptures/goodpage). AddRewriteinternally maps the.htmlrequest to the clean path, so your app serves the correct content.AddRedirectsends a 301 Permanent Redirect—critical for SEO, as it tells search engines to update their indexes to the new URL.
- The regex
Approach 2: Custom Middleware (Flexible Control)
If you need more flexibility (like excluding certain .html URLs or adding custom logic), a custom middleware is the way to go.
Add this middleware to your pipeline in Program.cs, again after UseStaticFiles() and before UseRouting():
app.Use(async (context, next) => { var requestPath = context.Request.Path.Value; // Check if the request ends with .html (case-insensitive) if (!string.IsNullOrEmpty(requestPath) && requestPath.EndsWith(".html", StringComparison.OrdinalIgnoreCase)) { // Remove the .html suffix var newPath = requestPath.Substring(0, requestPath.Length - 5); // Redirect permanently to the clean path context.Response.Redirect(newPath, permanent: true); return; // Skip further middleware processing } // Continue to the next middleware if no redirect is needed await next(); });
This gives you full control—you can add conditions like if (requestPath != "/special-exception.html") to skip redirects for specific pages.
Approach 3: Attribute Routing (Granular Page-by-Page)
If you only need to redirect a handful of pages, you can use attribute routing directly in your controllers. This is great for specific cases where you want to map both the old and new URLs to the same action, then redirect from the old one.
public class GoodPageController : Controller { // Maps both /goodpage and /goodpage.html to this action [Route("goodpage")] [Route("goodpage.html")] public IActionResult Index() { // If the request came from the .html URL, redirect to the clean path if (Request.Path.Value.EndsWith(".html", StringComparison.OrdinalIgnoreCase)) { return RedirectPermanent("/goodpage"); } return View(); } }
Key Notes
- Use 301 Redirects: Always use permanent redirects (301) instead of temporary (302) unless you plan to revert the change later. 301s are better for SEO and ensure users/browsers cache the new URL.
- Test Edge Cases: Make sure to test URLs with subdirectories (e.g.,
/subfolder/page.html)—all the above methods handle these correctly. - Avoid Double Redirects: Ensure your rewrite/redirect rules don't create loops (the regex patterns above are safe because they only match URLs ending with
.html).
内容的提问来源于stack exchange,提问作者realPro

