2009-09-24 1 views
7

Ich habe eine Anwendung hier mit einer Mischung aus Webform und MVC. Ich gebe Sie den Routing wie untenHtml.ActionLink konstruiere falsche Verbindung, wenn eine nicht-mvc Route hinzugefügt wird

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

Damit virtuellen Pfad auf „Upload/Neu“ tatsächlich Karten zu einer aspx webform Seite.

Aber mein Problem ist, dass Html.ActionLink ("Test", "Controller", "Aktion") macht jetzt

/Upload/neu? Regler = Regler & Action = Aktion

Nachdem ich mir den MVC-Quellcode angesehen habe, verstehe ich, dass ActionLink an RouteCollection.GetVirtualPath(requestContext, routeName, mergedRouteValues) anruft, wo routeName auf null gesetzt ist. Und irgendwie verwendet dies standardmäßig die AspxRoute-Route, um die URL zu erstellen. Ich habe versucht, eine andere Route vor "AspxRoute" hinzuzufügen, aber es scheint, dass es immer auf den Nicht-MCV-Routehandler eins ist.

Wie funktioniert RouteCollection.GetVirtualPath verhalten, wenn routeName null ist? Und warum verhält es sich so für meinen Fall?

Wie konstruiere ich eine korrekte URL? Muss ich eine neue HtmlHelper-Erweiterung schreiben?

Prost

Antwort

3

Versuchen:

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

Mit Routelink statt Action können Sie die Route, die Sie verwenden möchten, um anzugeben, die in diesem Fall die MVC Trassierung Standard ist als einer der Sitte gegen Du hast hinzugefügt.

+0

Hallo Dank. Ich weiß, dass RouteLink funktioniert, aber es ist nur ein kleines bisschen Unannehmlichkeit! All die magischen Saiten. Warum funktioniert ActionLink nicht? –

+0

Es enthält nur eine weitere Zeichenfolge als ActionLink und Ihre ursprüngliche Frage war "Wie konstruiere ich eine korrekte URL?". Der Grund, warum dies erforderlich ist, ist, dass Ihr WebFormRouteHandler eine "gültige" Routenkombination bereitstellt. Da er vor der Standardroute in der RouteTable hinzugefügt wird, wird er zuerst zurückgegeben. Aber wie auch immer, ich habe eine andere Antwort hinzugefügt, die Ihnen vielleicht besser gefällt. –

6

Eine alternative Option wäre das Hinzufügen einer benutzerdefinierten Einschränkung zu Ihren WebFormRoute (s). Beispielsweise könnten Sie eine Implementierung von IRouteConstraint erstellen, um RouteDirection.IncomingRequest zu entsprechen, und dann sicherstellen, dass die Route von servergenerierten Routen (wie ActionLink) ignoriert wird, aber immer noch von clientgenerierten Anforderungen verwendet wird. Etwas wie:

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

Und dann die Einschränkung Ihrer Route hinzufügen:

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

Natürlich können Sie es vorziehen, können Sie Ihre eigene Art von Einschränkung hinzuzufügen, dieser ganz auf der Strecke zu begrenzen, die sie implementiert , aber es ist nur ein Beispiel für eine Möglichkeit, das Problem zu lösen.

+0

Danke, ich habe diese Antwort benutzt, um eine weitere Frage von mir zu lösen. – JTew

+0

Großartig! genau das was ich gesucht habe! – gsobocinski

+1

Ich bedauere, dass ich nur eine Anregung für diese Antwort habe. –

2

Außerdem: Stellen Sie sicher, dass Ihre Standardroute der LAST-Eintrag in der Routingtabelle ist. Das ist ein weiterer einfacher Weg, um mit der Art von HTML-Aktion Link, die Sie bekommen.

+0

Frage von so langer Zeit immer noch Antworten bekommen :-) Wenn Sie den Code, den ich angehängt, betrachten, ist es der letzte Eintrag in der Routentabelle. MVC.net hat einen langen Weg zurückgelegt, vielleicht hat sich alles verändert, ich habe keine Ahnung! –

1

Ich habe das gleiche erlebt, wo die Routen korrekt "inbound" funktionierten, aber Html.ActionLink() wählte die falsche Route. Ich arbeitete um es durch eine Route Einschränkung hinzugefügt, so dass die controller leer sein muss:

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

Da der „Controller“ Route Wert nichts beschränkt ist, ein Aufruf an Actionlink() endet die Strecke zu ignorieren. Hoffe das hilft jemandem!

1

erzwingen die Standardroute keine Controller haben:

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