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:
- La página tiene una nueva ubicación.
- Deben hacer clic en el enlace si no se redirige automáticamente.
- 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