2009-09-24 2 views
7

Ho un'applicazione qui con un mix di webform e mvc. A specificare il percorso come di seguitoHtml.ActionLink crea un collegamento errato quando viene aggiunta una route non-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 
     ); 

In modo che il percorso virtuale per "Carica/Nuovo" mappe in realtà ad una pagina aspx modulo web.

Ma il mio problema è che Html.ActionLink ("Test", "Controller", "Azione") ora rende

/Upload/Nuovo? Regolatore = regolatore & Action = Azione

aver guardato il codice sorgente MVC, capisco che è perché ActionLink chiama a RouteCollection.GetVirtualPath(requestContext, routeName, mergedRouteValues), dove routeName è lasciato a null. E in qualche modo questa impostazione predefinita utilizza la route AspxRoute per costruire l'url. Ho provato ad aggiungere un altro percorso prima di "AspxRoute", ma sembra sempre impostato per default sul routehandler non-mvc.

Come si comporta RouteCollection.GetVirtualPath quando routeName è null? E perché si sta comportando in questo modo per il mio caso?

Come si crea un URL corretto? Devo scrivere una nuova estensione Htmlhelper?

Acclamazioni

risposta

3

Prova:

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

Utilizzando RouteLink invece di ActionLink consente di specificare il percorso che si desidera utilizzare, che in questo caso è il MVC mappatura percorso predefinito in contrapposizione a quello personalizzato tu hai aggiunto.

+0

Ciao, grazie. So che RouteLink funziona, ma è solo un piccolo inconveniente! Tutte le corde magiche. Perché ActionLink non funziona. –

+0

Contiene solo una stringa in più rispetto ad ActionLink e la tua domanda originale era "Come si costruisce un URL corretto?". Il motivo per cui questo è necessario è che WebFormRouteHandler fornisce una corrispondenza di route "valida" e, poiché viene aggiunta prima della route predefinita in RouteTable, viene restituita per prima. Ma comunque, ho aggiunto un'altra risposta che potrebbe essere più di tuo gradimento. –

6

Un'opzione alternativa sarebbe quella di aggiungere un vincolo personalizzato al proprio WebFormRoute (s). Ad esempio, è possibile creare un'implementazione di IRouteConstraint in modo che corrisponda a RouteDirection.IncomingRequest, quindi utilizzarlo per garantire che la route venga ignorata dalle rotte generate dal server (come ActionLink) ma ancora utilizzata dalle richieste generate dal client. Qualcosa di simile:

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

e quindi aggiungere il vincolo per il percorso:

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

Naturalmente si può scegliere di aggiungere il proprio stile di vincolo, questo è abbastanza limitante sulla rotta che lo implementa , ma è solo un esempio di come risolvere il problema.

+0

Grazie, ho usato questa risposta per sistemare un'altra mia domanda. – JTew

+0

Ottimo! esattamente quello che stavo cercando! – gsobocinski

+1

Mi rammarico di avere solo un upvote da dare per questa risposta. –

2

Inoltre: assicurarsi che il percorso predefinito sia l'ULTIMA entrata nella tabella di routing. Questo è un altro modo semplice per finire con il tipo di link di azione html che stai ottenendo.

+0

Domanda da tanto tempo fa ancora ottenere risposte :-) se si guarda il codice che ho allegato, è l'ultima voce nella tabella del percorso. MVC.net ha fatto molta strada, forse tutto è cambiato, non ne ho idea! –

1

ho sperimentato la stessa cosa in cui i percorsi hanno lavorato correttamente "inbound", ma Html.ActionLink() stava raccogliendo la strada sbagliata. Ho lavorato intorno aggiungendo un vincolo percorso in modo che il controller deve essere vuoto:

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

Poiché il valore percorso "controller" è limitato a nulla, una chiamata a ActionLink() finisce per ignorare il percorso. Spero che questo aiuti qualcuno!

1

vigore le impostazioni predefinite di percorso per avere nessun controller:

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