2009-09-24 20 views
7

Tengo una aplicación aquí con una mezcla de formulario web y mvc. Especifico el enrutamiento de la siguiente maneraHtml.ActionLink construye un enlace incorrecto cuando se agrega una ruta que no es mvc

 routes.Add("AspxRoute", new Route("Upload/New", new WebFormRouteHandler<Page>("~/Uploads.aspx"))); 

     routes.MapRoute(
      "Default",            // Route name 
      "{controller}/{action}/{id}",       // URL with parameters 
      new { controller = "Home", action = "Index", id = "" } // Parameter defaults 
     ); 

Así que camino virtual a "Subir/Nueva" en realidad se correlaciona con una página aspx formulario web.

Pero mi problema es que Html.ActionLink ("Prueba", "controlador", "Acción") ahora hace

/Subir/Novedades Controller = Controlador & Action = Acción

Después de haber examinado el código fuente de MVC, entiendo que es porque ActionLink llama a RouteCollection.GetVirtualPath(requestContext, routeName, mergedRouteValues), donde routeName se deja nulo. Y de alguna manera esto predetermina usar la ruta AspxRoute para construir la url. Intenté agregar otra ruta antes de "AspxRoute", pero parece que siempre está por defecto en el controlador de ruta que no es mvc.

¿Cómo se comportan RouteCollection.GetVirtualPath cuando routeName es nulo? ¿Y por qué se está comportando así en mi caso?

¿Cómo construyo una URL correcta? ¿Debo escribir una nueva extensión Htmlhelper?

Saludos

Respuesta

3

Probar:

<%=Html.RouteLink("Test", "Default", new {controller = "Controller", action = "Action"})%> 

Usando RouteLink en lugar de ActionLink le permite especificar la ruta que desea utilizar, que en este caso es la asignación de ruta MVC defecto en contraposición a la costumbre uno Has añadido.

+0

Hola, gracias. Sé que RouteLink funciona, ¡pero es solo un pequeño inconveniente! Todas las cuerdas mágicas. ¿Por qué ActionLink no funciona? –

+0

Solo contiene una cadena más que ActionLink y su pregunta original fue "¿Cómo construyo una URL correcta?". La razón por la que esto es necesario es que su WebFormRouteHandler proporciona una coincidencia de ruta "válida", y como se agrega antes de su ruta predeterminada en la RouteTable, se devuelve primero. Pero de todos modos, he agregado otra respuesta que puede ser más de su agrado. –

6

Una opción alternativa sería agregar una restricción personalizada a su WebFormRoute (s). Por ejemplo, podría crear una implementación de IRouteConstraint para que coincida con RouteDirection.IncomingRequest, y luego usarla para asegurar que las rutas generadas por el servidor (como ActionLink) ignoren la ruta pero que las solicitudes generadas por el cliente todavía las utilicen. Algo así como:

public class IncomingOnlyRouteConstraint: IRouteConstraint 
{ 
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     if (routeDirection == RouteDirection.IncomingRequest) 
     { 
      return true; 
     } 
     return false; 
    } 
} 

y luego añadir la restricción a la ruta:

routes.Add("AspxRoute", new Route("Upload/New", null, 
          new RouteValueDictionary() { {"WebFormsConstraint", new IncomingOnlyRouteConstraint()} }, 
          new WebFormRouteHandler<Page>("~/Uploads.aspx"))); 

Por supuesto, es posible que prefiera para añadir su propio estilo de restricción, éste es bastante limitante en la ruta que lo implementa , pero es solo un ejemplo de una forma en que podrías resolver el problema.

+0

Gracias, utilicé esta respuesta para arreglar otra pregunta mía. – JTew

+0

¡Genial! ¡Exactamente lo que estaba buscando! – gsobocinski

+1

Lamento tener solo un voto para dar para esta respuesta. –

2

También: asegúrese de que su ruta predeterminada sea la ÚLTIMA entrada en la tabla de enrutamiento. Esa es otra manera fácil de terminar con el tipo de enlace de acción html que está recibiendo.

+0

Pregunta de hace tanto tiempo sigue obteniendo respuestas :-) si nos fijamos en el código que adjunté, es la última entrada en la tabla de rutas. MVC.net ha recorrido un largo camino, tal vez todo ha cambiado, ¡no tengo ni idea! –

1

Experimenté lo mismo cuando las rutas funcionaban correctamente como "entrantes", pero Html.ActionLink() estaba tomando la ruta incorrecta. Trabajé alrededor de ella mediante la adición de una restricción de ruta para que el controller debe estar vacío:

var constraints = new RouteValueDictionary() 
{ 
    { "controller", string.Empty } 
}; 

routes.Add(new Route("sso/server", null, constraints, new OpenIDServerRouteHandler())); 

routes.MapRoute(
    name: "Default", 
    url: "{controller}/{action}/{identity}", 
    defaults: new { controller = "Pages", action = "Home", identity = UrlParameter.Optional } 
); 

Dado que el valor ruta "controlador" se limita a la nada, una llamada a ActionLink() termina haciendo caso omiso de la ruta. ¡Espero que esto ayude a alguien!

1

fuerza los valores por defecto de la ruta tenga ningún controlador:

var routeDefaults = new RouteValueDictionary() { { "controller", null } }; 
routes.Add("RouteName", new Route("some/path", routeDefaults, new SomeHandler())); 
Cuestiones relacionadas