如何为遗留C#/ASP.NET Web Forms应用添加页面路由实现友好URL
ASP.NET Web Forms 自定义路由实现方案
前置依赖配置
首先确认项目已引用System.Web.Routing程序集,然后修改Web.config添加以下配置:
<system.web> <pages> <namespaces> <add namespace="System.Web.Routing" /> </namespaces> </pages> </system.web> <system.webServer> <modules runAllManagedModulesForAllRequests="true"> <remove name="UrlRoutingModule" /> <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" preCondition="managedHandler" /> </modules> <handlers> <add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> </handlers> </system.webServer>
路由规则注册
在项目根目录的Global.asax.cs文件中添加路由注册逻辑,路由规则按从精确到模糊的顺序注册,避免匹配错乱:
using System.IO; using System.Web; using System.Web.Routing; public class Global : HttpApplication { void Application_Start(object sender, EventArgs e) { RegisterRoutes(RouteTable.Routes); } public static void RegisterRoutes(RouteCollection routes) { // 忽略系统内置资源路径 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // 全局路由配置:自动忽略末尾斜杠、统一URL小写 routes.AppendTrailingSlash = false; routes.LowercaseUrls = true; // 1. Account前缀路由规则 routes.MapPageRoute( routeName: "AccountPages", routeUrl: "account/{pageName}", physicalFile: "~/Account/{pageName}.aspx", checkPhysicalUrlAccess: true, defaults: new RouteValueDictionary(), constraints: new RouteValueDictionary { { "pageName", new PageExistsConstraint("~/Account/") } } ); // 2. 根路径默认首页路由 routes.MapPageRoute( routeName: "RootDefault", routeUrl: "", physicalFile: "~/Pages/Default.aspx", checkPhysicalUrlAccess: true ); // 3. Pages文件夹下的普通页面路由 routes.MapPageRoute( routeName: "ContentPages", routeUrl: "{pageName}", physicalFile: "~/Pages/{pageName}.aspx", checkPhysicalUrlAccess: true, defaults: new RouteValueDictionary(), constraints: new RouteValueDictionary { { "pageName", new PageExistsConstraint("~/Pages/") } } ); // 4. 兜底404路由,匹配所有未命中规则的路径 routes.MapPageRoute( routeName: "NotFound", routeUrl: "{*url}", physicalFile: "~/Pages/Error404.aspx", checkPhysicalUrlAccess: true ); } } // 自定义约束:校验对应路径下的aspx文件是否真实存在 public class PageExistsConstraint : IRouteConstraint { private readonly string _basePath; public PageExistsConstraint(string basePath) { _basePath = basePath; } public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { if (values.TryGetValue(parameterName, out object pageNameObj) && pageNameObj is string pageName) { string fullPhysicalPath = HttpContext.Current.Server.MapPath($"{_basePath}{pageName}.aspx"); return File.Exists(fullPhysicalPath); } return false; } }
404页面补充配置
在~/Pages/Error404.aspx的后台代码中添加状态码设置,确保返回标准404响应,避免被IIS默认错误页覆盖:
protected void Page_Load(object sender, EventArgs e) { Response.StatusCode = 404; Response.TrySkipIisCustomErrors = true; }
效果验证
所有规则完全匹配需求:
myurl.com/account/login映射到~/Account/Login.aspx,仅当对应aspx文件存在时才会命中规则- 根路径
myurl.com/映射到~/Pages/Default.aspx myurl.com/foo映射到~/Pages/foo.aspx,仅当对应aspx文件存在时才会命中规则- 所有未匹配成功的多段路径、不存在的页面路径统一走
~/Pages/Error404.aspx - 默认自动忽略URL末尾斜杠,多段路径不会错误匹配单段路由规则
内容的提问来源于stack exchange,提问作者blcamp
相关产品推荐
相关产品推荐

