ASP.Net MVC路由捕获所有* .aspx请求

以前一定要问过这个问题,但是在这里阅读之后, 这里 , 这里和这里我都无法推断相关部分以使其发挥作用。 我正在将旧的Web表单站点修改为MVC,并希望捕获特定的传入HTTP请求,以便我可以发出RedirectPermanent (以保护我们的Google排名并避免用户因404而离开)。

我不是拦截所有传入的请求,也不是解析某些id值,而是拦截所有以.aspx文件扩展名结尾(或包含)的请求,例如

 www.sample.com/default.aspx www.sample.com/somedir/file.aspx www.sample.com/somedir/file.aspx?foo=bar 

应忽略对MVC路由的请求(只是正常处理)。

这是我到目前为止ASPXFiles ,除了ASPXFiles路线永远不会被击中。

 public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // never generates a match routes.MapRoute( name: "ASPXFiles", url: "*.aspx", defaults: new { controller = "ASPXFiles", action = "Index" } ); // Used to process all other requests (works fine) routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } } 

}

这种类型的路由是否可以在MVC中设置?

我正在展示在MVC中进行301重定向的正确方法,因为并非所有浏览器都能正确响应301重定向请求,并且您需要为用户提供继续选项,而不是ASP生成的默认“Object Moved”页面。净。

RedirectAspxPermanentRoute

我们构建了一个自定义RouteBase子类,它检测URL何时以.aspx结尾,并路由到我们的SystemController以设置301重定向。 它要求您将URL(要匹配的URL)的映射传递给路由值(用于生成MVC URL)。

 public class RedirectAspxPermanentRoute : RouteBase { private readonly IDictionary urlMap; public RedirectAspxPermanentRoute(IDictionary urlMap) { if (urlMap == null) throw new ArgumentNullException("urlMap"); this.urlMap = urlMap; } public override RouteData GetRouteData(HttpContextBase httpContext) { var path = httpContext.Request.Path; if (path.EndsWith(".aspx")) { if (!urlMap.ContainsKey(path)) return null; var routeValues = urlMap[path]; var routeData = new RouteData(this, new MvcRouteHandler()); routeData.Values["controller"] = "System"; routeData.Values["action"] = "Status301"; routeData.DataTokens["routeValues"] = routeValues; return routeData; } return null; } public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { return null; } } 

请注意,第一次检查是针对.aspx扩展名的,因此如果扩展名不匹配,则将完全跳过其余逻辑。 这将为您的方案提供最佳性能。

SystemController

我们设置SystemController以像往常一样返回视图。 如果浏览器由于301而没有重定向,则用户将看到该视图。

 using System; using System.Net; using System.Web; using System.Web.Mvc; public class SystemController : Controller { // // GET: /System/Status301/ public ActionResult Status301() { var routeValues = this.Request.RequestContext.RouteData.DataTokens["routeValues"]; var url = this.GetAbsoluteUrl(routeValues); Response.CacheControl = "no-cache"; Response.StatusCode = (int)HttpStatusCode.MovedPermanently; Response.RedirectLocation = url; ViewBag.DestinationUrl = url; return View(); } private string GetAbsoluteUrl(object routeValues) { var urlBuilder = new UriBuilder(Request.Url.AbsoluteUri) { Path = Url.RouteUrl(routeValues) }; var encodedAbsoluteUrl = urlBuilder.Uri.ToString(); return HttpUtility.UrlDecode(encodedAbsoluteUrl); } } 

Status301.cshtml

遵循MVC的惯例,并确保将其放在/Views/System/文件夹中。

因为它是301响应的视图,所以您可以使其与您网站其余部分的主题相匹配。 所以,如果用户在这里结束,那仍然是一个糟糕的经历。

该视图将尝试通过JavaScript Meta-Refresh自动重定向用户。 这两个都可以在浏览器中关闭,但用户可能会把它放到应该去的地方。 如果没有,你应该告诉用户:

  1. 该页面有一个新位置。
  2. 如果没有自动重定向,他们需要单击链接。
  3. 他们应该更新他们的书签。

 @{ ViewBag.Title = "Page Moved"; } @section MetaRefresh {  } 

Page Moved

The page has moved. Click on the following URL if you are not redirected automatically in 5 seconds. Be sure to update your bookmarks.

https://stackoverflow.com/questions/36156496/asp-net-mvc-route-to-catch-all-aspx-requests/@ViewBag.DestinationUrl.

用法

首先,您需要在_Layout.cshtml添加一个部分,以便可以将元刷新添加到页面的head部分。

     @ViewBag.Title - My ASP.NET MVC Application   @RenderSection("MetaRefresh", required: false)  @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr")    

然后将RedirectAspxRoute添加到路由配置中。

 public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.Add(new RedirectAspxPermanentRoute( new Dictionary() { // Old URL on the left, new route values on the right. { @"/about-us.aspx", new { controller = "Home", action = "About" } }, { @"/contact-us.aspx", new { controller = "Home", action = "Contact" } } }) ); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } } 

尝试这样的事情:

  routes.MapRoute( name: "ASPXFilesWithFolderPath", url: "{folder}/{page}.aspx", defaults: new { controller = "ASPXFiles", action = "Index", folder=UrlParameter.Optional, page = UrlParameter.Optional } ); routes.MapRoute( name: "ASPXFiles", url: "{page}.aspx", defaults: new { controller = "ASPXFiles", action = "Index", page = UrlParameter.Optional } ); 

最初我打算和HTTPHandler建议但是默认情况下aspx扩展名在IIS中映射,因此不起作用。 这是Jon Galloway博客的链接