c# asp.net asp.net-mvc asp.net-mvc-5 asp.net-mvc-routing

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



asp.net-mvc asp.net-mvc-5 (2)

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 una opción para continuar en lugar de la página predeterminada "Objeto movido" que genera ASP .RED.

RedirectAspxPermanentRoute

Creamos una subclase de RouteBase personalizada que detecta cuándo una URL termina con .aspx y se dirige a nuestro SystemController para configurar la redirección 301. Requiere que pase un mapa de URL (la URL que debe coincidir) para enrutar valores (que se utilizan para generar la URL MVC).

public class RedirectAspxPermanentRoute : RouteBase { private readonly IDictionary<string, object> urlMap; public RedirectAspxPermanentRoute(IDictionary<string, object> 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 resto de la lógica se omitirá por completo si la extensión no coincide. Esto proporcionará el mejor rendimiento para su escenario.

Controlador del sistema

Configuramos el SystemController para devolver una vista como lo haríamos normalmente. Si el navegador no redirige debido a la 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 resto de su sitio. Entonces, si el usuario termina aquí, todavía no es una mala experiencia.

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

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

@{ ViewBag.Title = "Page Moved"; } @section MetaRefresh { <meta http-equiv="refresh" content="5;@ViewBag.DestinationUrl" /> } <h2 class="error">Page Moved</h2> <p> The page has moved. Click on the following URL if you are not redirected automatically in 5 seconds. Be sure to update your bookmarks. </p> <a href="@ViewBag.DestinationUrl">@ViewBag.DestinationUrl</a>. <script> //<!-- setTimeout(function () { window.location = "@ViewBag.DestinationUrl"; }, 5000); //--> </script>

Uso

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

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>@ViewBag.Title - My ASP.NET MVC Application</title> <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" /> <!-- Add this so the view can update this section --> @RenderSection("MetaRefresh", required: false) <meta name="viewport" content="width=device-width" /> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") </head> <!-- layout code omitted --> </html>

Luego 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<string, object>() { // 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 } ); } }

Esto debe haberse preguntado antes, pero después de leer here , here , here y here no puedo extrapolar las partes relevantes para que funcione. Estoy renovando un antiguo sitio de formularios web en MVC, y quiero captar solicitudes HTTP entrantes particulares para poder emitir un RedirectPermanent (para proteger nuestras clasificaciones 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 , necesito 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 MVC deben ser ignoradas (solo procesadas de manera normal).

Esto es lo que tengo hasta ahora, excepto que la ruta ASPXFiles nunca se ve afectada.

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 configurar este tipo de ruta en MVC?


Intenta 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 y 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