Ruta ASP.Net MVC para capturar todas las solicitudes * .aspx

Esto debe haberse preguntado antes, pero después de leer aquí , aquí , aquí y aquí no puedo extrapolar las partes relevantes para que funcione. Estoy modernizando un sitio antiguo de formularios web en MVC, y quiero detectar solicitudes HTTP entrantes particulares para poder emitir un RedirectPermanent (para proteger nuestros rankings de Google y evitar que los usuarios se vayan debido a los 404).

En lugar de interceptar todas las solicitudes entrantes, o analizar algún valor de id , tengo que interceptar todas las solicitudes que terminan en (o contienen) la extensión de archivo .aspx , por ejemplo

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

Las solicitudes a las rutas de MVC se deben ignorar (solo se procesan de forma normal).

Esto es lo que tengo hasta ahora, excepto que la ruta ASPXFiles nunca se está 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 } ); } } 

}

¿Es posible establecer este tipo de ruta en MVC?

Estoy mostrando la forma correcta de hacer una redirección 301 en MVC, ya que no todos los navegadores responden correctamente a las solicitudes de redireccionamiento 301, y debe darle al usuario la opción de continuar en lugar de la página predeterminada “Objeto movido” que genera ASP. .RED.

RedirectAspxPermanentRoute

Construimos una subclase personalizada de RouteBase que detecta cuándo termina una URL con .aspx y se dirige a nuestro SystemController para configurar la redirección 301. Requiere que ingrese un mapa de URL (la URL para hacer coincidir) con los valores de ruta (que se usan para generar la URL de MVC).

 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; } } 

Tenga en cuenta que la primera comprobación es para la extensión .aspx , por lo que el rest de la lógica se saltará por completo si la extensión no coincide. Esto proporcionará el mejor rendimiento para su escenario.

SystemController

Configuramos SystemController para devolver una vista como lo haríamos normalmente. Si el navegador no se redirecciona debido al 301, el usuario verá la vista.

 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

Siga las convenciones de MVC y asegúrese de colocar esto en la carpeta /Views/System/ .

Debido a que es una vista para su respuesta 301, puede hacer que coincida con el tema del rest de su sitio. Entonces, si el usuario termina aquí, no es una mala experiencia.

La vista intentará redirigir al usuario automáticamente a través de JavaScript y a través de Meta-Refresh. Ambos pueden desactivarse en el navegador, pero es probable que el usuario llegue a donde se supone que debe ir. De lo contrario, debe decirle al usuario:

  1. La página tiene una nueva ubicación.
  2. Deben hacer clic en el enlace si no se redirigen automáticamente.
  3. Deben actualizar su marcador.

 @{ 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.

Uso

Primero, debe agregar una sección a su _Layout.cshtml para que Meta-refresh se pueda agregar a la sección principal de su página.

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

A continuación, agregue RedirectAspxRoute a su configuración de enrutamiento.

 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 } ); } } 

Pruebe algo como esto:

  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 } ); 

Inicialmente, iba a sugerir HTTPHandler pero la extensión aspx está asignada en IIS de forma predeterminada y, por lo tanto, no funcionará. Aquí hay un enlace al blog de Jon Galloway