2012-04-05 7 views
3

Entschuldigung für eine Frage eher N00b, ich bin ziemlich neu in ASP.NET MVC. Mein Problem ist wie folgt:MVC 3 Fall-Through-Routing

Ich möchte meine Website eine URL in der folgenden Art und Weise zu handhaben:

www.mysite.com/homepage/name 

ich den Link oben das Profil des Benutzers zu gehen. Der Einfachheit halber ist der Controller der Homepage-Controller mit der Test-Aktion.

Was bedeutet, dass die global.asax Routing wird:

routes.MapRoute(
      "test", 
      "homepage/{name}", 
      new { controller = "Homepage", action = "Test" } 
      ); 

Bis jetzt der Code funktioniert gut (ich es getestet und es Routen ok).

Aber jetzt meine andere Funktionalität, die ich will, ist zu aktivieren:

www.mysite.com/homepage/action/id 

als gut zu funktionieren.

Das Routing für diese sein wird:

routes.MapRoute(
      "Default", 
      "homepage/{action}/{id}", 
      new { controller = "Homepage", action = "Index", id = UrlParameter.Optional } 
     ); 

Das Problem ist, was passiert, wenn ein Benutzer die {id} für eine Aktion, die Routing-Tabelle wegzulassen feststellt, dass der Aktionsname tatsächlich der {Name ist } Parameter.

Gibt es eine Möglichkeit, zuerst zu überprüfen, ob eine Aktion existiert. Und nur wenn dies nicht der Fall ist, verwenden Sie es als Parameter für eine andere Route.

Macht Sinn? Wenn nicht, füge ich noch weitere Details hinzu.

Danke!

EDIT

So habe ich es geschafft habe, diese zu lösen die Einschränkungen mit regex Ich legte einen regulären Ausdruck definiert, ein alle Aktionen in meinem Controller:

routes.MapRoute(
      "homepage", 
      "homepage/{action}/{id}", 
      new { controller = "Homepage", action = "Index", id = UrlParameter.Optional }, 
      new { action = "(action1|action2|action3)" } 
      ); 

Und dann die nächste Regel:

routes.MapRoute(
      "feed", 
      "homepage/{id}", 
      new { controller = "Homepage", action = "Test"} 
      ); 

Ich arbeite ok, nur ist es schwer zu skalieren. Sie müssen daran denken, jede neue Aktion auf den Controller innerhalb der Zeichenfolge hier zu platzieren. Es ist eine große Öffnung für Debug-Albträume.

Vielen Dank!

+0

Was passiert, wenn ein Benutzer ein Konto mit dem Namen Index erstellt, oder was auch immer Ihr Aktionsname ist? –

+0

Ich vermute, dass alles mit DB-Management synchronisiert werden muss. Es ist eine gute Frage. Die Art und Weise, wie wir es tun, erzeugt diese Schnecken selbst, also behalten wir uns das Recht vor, einige Strings zu reservieren. – oamsel

+0

Ich denke, mein Punkt ist, dass es wirklich besser ist, Dinge so zu konstruieren, dass solche Verwirrungen nicht auftreten können, wenn man einen anderen Pfad benutzt. –

Antwort

0

Sie müssen zuerst den Default Weg bringen, und auch seine zulässigen Werte beschränken

routes.MapRoute(
      "Default", 
      "homepage/{action}/{id}", 
      new { controller = "Homepage", action = "Index", id = UrlParameter.Optional }, 
      new {action = @"Index|Delete|Add"} 
     ); 

routes.MapRoute(
      "test", 
      "homepage/{name}", 
      new { controller = "Homepage", action = "Test" } 
      ); 

diese Weise wird die erste Route wird nur dann, wenn der Wert übereinstimmt in der Einschränkung versehen Aktion verwendet werden, sonst wird es bewegen zur nächsten Regel.

Sie müssen auch sicherstellen, dass beim Erstellen von Benutzerprofilen kein Name mit einer Ihrer unterstützten Aktionen für die Route default übereinstimmt.

+0

Danke. Wie ich den Beitrag bearbeitet habe, funktioniert es. aber es ist schwer zu skalieren. Danke vielmals ! – oamsel

+0

@Omer, wenn Sie *** on-the-fly *** überprüfen möchten, ob die Aktion vorhanden ist, dann schauen Sie sich diese Antwort von frenky on an [So stellen Sie sicher, dass Controller und Aktion existieren, bevor Sie redirect, asp.net mvc3] (http://stackoverflow.com/a/7036978/128165) –

+0

Es sieht gut aus. Gibt es eine Chance, dass mein Routing verlangsamt wird? Gibt es hier einen Effizienzverlust? – oamsel

1

Da ASP.NET MVC die erste Route von RouteTable auswählt, die der aktuellen Anforderung entspricht, sollten Sie dieses Problem beheben können, indem Sie die Reihenfolge der Routen in Global.asax ändern.

Zuerst dies:

routes.MapRoute(
      "Default", 
      "homepage/{action}/{id}", 
      new { controller = "Homepage", action = "Index", id = UrlParameter.Optional } 
     ); 

und dann das:

routes.MapRoute(
      "test", 
      "homepage/{name}", 
      new { controller = "Homepage", action = "Test" } 
      ); 

Hoffnung, das hilft.

+1

auf diese Weise wird die zweite Route nie erreicht werden .. Sie sollten eine Einschränkung für die "Aktion" verwenden, um nur eine bestimmte Liste von "Aktionen" zu erlauben –

+0

Ja, Sie haben Recht. – philipproplesch

+0

Es hilft nicht. Es versucht immer noch, das ID-Feld als Aktion zu analysieren und gibt 404 nicht gefunden zurück. – oamsel