ASP.NET Core如何重定向至IIS配置的正确大小写站点URL?
ASP.NET Core IIS 大小写URL重定向与站点URL获取方案
为什么WebHostDefaults.ServerUrlsKey在服务器上返回null
WebHostDefaults.ServerUrlsKey是用于配置Kestrel监听地址的参数,而IIS部署时,ASP.NET Core是作为托管进程运行,实际的站点绑定域名、路径由IIS控制,因此这个参数在服务器环境下不会返回IIS的实际站点URL。
方案一:IIS URL重写规则(无代码实现)
直接在IIS层面配置重写规则,无需修改应用代码,适配多站点独立部署的需求:
- 打开站点的IIS管理器,找到URL重写模块
- 添加一条新规则,配置如下:
- 规则名称:
Correct Case Redirect - 匹配URL:
^myapp(.*)$(替换为你的小写路径前缀) - 条件:添加条件,输入
{REQUEST_URI},模式^/myApp(替换为你的正确大小写路径),勾选“否定” - 操作:选择“重定向”,目标URL填写
/myApp{R:1},重定向类型选“永久(301)”
- 规则名称:
对应的web.config配置代码如下:
<rewrite> <rules> <rule name="Correct Case Redirect" stopProcessing="true"> <match url="^myapp(.*)$" /> <conditions> <add input="{REQUEST_URI}" pattern="^/myApp" negate="true" /> </conditions> <action type="Redirect" url="/myApp{R:1}" redirectType="Permanent" /> </rule> </rules> </rewrite>
优点:性能高、无需改动应用,每个站点可独立配置对应规则。
方案二:ASP.NET Core中间件动态重定向(代码实现)
如果需要通过代码统一处理,可通过配置文件结合中间件实现,避免硬编码:
步骤1:配置正确路径
在每个站点的appsettings.json中添加对应站点的正确路径:
{ "CorrectSitePath": "/myApp" }
步骤2:编写重定向中间件
using Microsoft.AspNetCore.Http; public class CaseCorrectRedirectMiddleware { private readonly RequestDelegate _next; private readonly string _correctPath; public CaseCorrectRedirectMiddleware(RequestDelegate next, IConfiguration configuration) { _next = next; _correctPath = configuration["CorrectSitePath"] ?? string.Empty; } public async Task InvokeAsync(HttpContext context) { var requestPath = context.Request.Path.ToString(); // 检查请求路径是否匹配小写前缀,但不等于正确大小写路径 if (!string.IsNullOrEmpty(_correctPath) && requestPath.StartsWith(_correctPath.ToLower(), StringComparison.OrdinalIgnoreCase) && !requestPath.Equals(_correctPath, StringComparison.Ordinal)) { // 构造完整的正确URL var correctUrl = $"{context.Request.Scheme}://{context.Request.Host}{_correctPath}{requestPath.Substring(_correctPath.Length)}"; context.Response.Redirect(correctUrl, permanent: true); return; } await _next(context); } } // 中间件注册扩展 public static class MiddlewareExtensions { public static IApplicationBuilder UseCaseCorrectRedirect(this IApplicationBuilder builder) { return builder.UseMiddleware<CaseCorrectRedirectMiddleware>(); } }
步骤3:注册中间件
在Program.cs中,将中间件注册在路由中间件之前:
var builder = WebApplication.CreateBuilder(args); // 注册其他服务... var app = builder.Build(); // 注册大小写重定向中间件 app.UseCaseCorrectRedirect(); // 注册静态文件、路由等其他中间件... app.Run();
每个站点部署时,仅需修改自身的appsettings.json配置即可,无需改动代码。
方案三:读取IIS站点配置(Windows专属)
如果不想用配置文件,可通过Windows API读取IIS站点绑定信息,但仅适用于Windows环境,且需要应用池身份具备读取IIS配置的权限:
- 安装
Microsoft.Web.AdministrationNuGet包 - 编写读取代码:
using Microsoft.Web.Administration; public static string GetCorrectSiteUrl() { using (var serverManager = new ServerManager()) { // 通过应用物理路径匹配当前站点 var site = serverManager.Sites.FirstOrDefault(s => s.Applications.Any(a => a.VirtualDirectories.Any(v => v.PhysicalPath.Equals(AppContext.BaseDirectory, StringComparison.OrdinalIgnoreCase)))); if (site == null) return string.Empty; // 获取第一个HTTP/HTTPS绑定 var binding = site.Bindings.FirstOrDefault(b => b.Protocol is "http" or "https"); if (binding == null) return string.Empty; var scheme = binding.Protocol == "https" ? "https" : "http"; var hostPort = binding.Host.Length > 0 ? $"{binding.Host}:{binding.EndPoint.Port}" : binding.EndPoint.ToString(); var appPath = site.Applications.First().VirtualPaths.First().Path; return $"{scheme}://{hostPort}{appPath}"; } }
此方法局限性大,仅推荐Windows专属部署场景。
内容的提问来源于stack exchange,提问作者user1325179
相关产品推荐
相关产品推荐

