2008-09-04 22 views
3

Ich suche für einige Beispiele oder Proben von Routing für die folgende Art von Szenario:Kategorien von Controllern in MVC Routing? (Doppelte Controller-Namen in separater Namespaces)

Das allgemeine Beispiel, Dinge zu tun ist: {Controller}/{Aktion}/{id }

So im Szenario für ein Geschäft, ein Produkt der Suche nach tun würden Sie haben:

public class ProductsController: Controller 
{ 
    public ActionResult Search(string id) // id being the search string 
    { ... } 
} 

Sagen Sie ein paar Geschäfte haben, dies zu tun, und Sie, dass konsequent wollten, ist es eine Möglichkeit, dann have: {Kategorie}/{Controller}/{Aktion}/{ID}

Sie können also gezielt nach einem bestimmten Geschäft suchen, aber eine andere Suchmethode für ein anderes Geschäft verwenden?

(Wenn Sie die Speichernamen erforderlich, um eine höhere Priorität als die Funktion selbst in der URL zu sein)

Oder wäre es herunter zu kommen:

public class ProductsController: Controller 
{ 
    public ActionResult Search(int category, string id) // id being the search string 
    { 
     if(category == 1) return Category1Search(); 
     if(category == 2) return Category2Search(); 
     ... 
    } 
} 

Es ist nicht ein gutes Beispiel sein kann, aber im Grunde ist die Idee, den gleichen Controller-Namen zu verwenden und daher eine einfache URL über ein paar verschiedene Szenarien, oder bist du irgendwie mit dem Erfordern von eindeutigen Controller-Namen, und keine Möglichkeit, sie in etwas andere Namespaces/Verzeichnisse zu stecken stecken?

bearbeiten hinzuzufügen:

Der andere Grund, warum ich das will, ist, weil ich eine URL, die die Kategorien haben wollen könnte, und dass bestimmte Controller nur unter bestimmten Kategorien arbeiten.

IE:

/diese/Suche/Produkte/Suche + Begriff < - arbeitet

/das/Suche/Artikel/search + Begriff < - wird nicht funktionieren - weil die Suchsteuerung ist nicht erlaubt.

+0

Bezieht sich das Konzept der "Bereiche" in der Version 1.0 darauf? – hometoast

Antwort

1

Der beste Weg, dies ohne Kompromisse zu tun, wäre die Implementierung einer eigenen ControllerFactory durch Erben von IControllerFactory. Die CreateController-Methode, die Sie implementieren, behandelt die Erstellung der Controller-Instanz zur Verarbeitung der Anforderung durch RouteHandler und ControllerActionInvoker. Die Konvention besteht darin, den Namen des Controllers beim Erstellen zu verwenden. Daher müssen Sie diese Funktionalität überschreiben. Hier werden Sie Ihre benutzerdefinierte Logik zum Erstellen des Controllers basierend auf der Route einfügen, da Sie mehrere Controller mit demselben Namen, aber in verschiedenen Ordnern haben. Dann müssen Sie Ihre benutzerdefinierte Controller-Factory beim Start der Anwendung registrieren, genau wie Ihre Routen.

Ein weiterer Bereich, den Sie berücksichtigen müssen, ist das Finden Ihrer Ansichten beim Erstellen des Controllers. Wenn Sie für alle die gleiche Ansicht verwenden möchten, sollten Sie nichts anderes tun als die verwendete Konvention. Wenn Sie auch Ihre Ansichten organisieren möchten, müssen Sie auch Ihren eigenen ViewLocator erstellen und ihn dem Controller zuweisen, wenn Sie ihn in Ihrer Controller Factory erstellen.

Um eine Idee von Code zu bekommen, gibt es ein paar Fragen, die ich auf SO beantwortet habe, die sich auf diese Frage beziehen, aber dieser ist zu einem gewissen Grad anders, weil die Controllernamen gleich sein werden. Ich habe Links als Referenz eingefügt.

Ein anderer Weg, kann aber einige Kompromisse erfordern die neuen AcceptVerbs zu verwenden sein Attribut. Überprüfen Sie diese question für weitere Details. Ich habe noch nicht mit dieser neuen Funktionalität gespielt, aber es könnte eine andere Route sein.

4

Ich fand es tatsächlich nicht einmal durch Suchen, sondern durch Scannen durch die ASP .NET Foren in this question.

diese verwenden Sie können die Controller mit dem gleichen Namen unter jedem Teil des Namespace haben, so lange, wie Sie qualifizieren, welche Routen gehören, auf die Namespaces (Sie mehrere Namespaces pro Routen haben können, wenn Sie sein müssen!)

Aber von hier aus können Sie ein Verzeichnis unter Ihrem Controller einfügen, also wenn Ihr Controller "MyWebShop.Controllers" wäre, würden Sie ein Verzeichnis von "Shop1" setzen und der Namespace wäre "MyWebShop.Controllers.Shop1"

Dann funktioniert das:

public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

     var shop1namespace = new RouteValueDictionary(); 
     shop1namespace.Add("namespaces", new HashSet<string>(new string[] 
     { 
      "MyWebShop.Controllers.Shop1" 
     })); 

     routes.Add("Shop1", new Route("Shop1/{controller}/{action}/{id}", new MvcRouteHandler()) 
     { 
      Defaults = new RouteValueDictionary(new 
      { 
       action = "Index", 
       id = (string)null 
      }), 
      DataTokens = shop1namespace 
     }); 

     var shop2namespace = new RouteValueDictionary(); 
     shop2namespace.Add("namespaces", new HashSet<string>(new string[] 
     { 
      "MyWebShop.Controllers.Shop2" 
     })); 

     routes.Add("Shop2", new Route("Shop2/{controller}/{action}/{id}", new MvcRouteHandler()) 
     { 
      Defaults = new RouteValueDictionary(new 
      { 
       action = "Index", 
       id = (string)null 
      }), 
      DataTokens = shop2namespace 
     }); 

     var defaultnamespace = new RouteValueDictionary(); 
     defaultnamespace.Add("namespaces", new HashSet<string>(new string[] 
     { 
      "MyWebShop.Controllers" 
     })); 

     routes.Add("Default", new Route("{controller}/{action}/{id}", new MvcRouteHandler()) 
     { 
      Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" }), 
      DataTokens = defaultnamespace    
     }); 
    } 

Die einzige andere Sache ist, dass es auf eine Ansicht verweist, die sich noch im Basisverzeichnis befindet. Wenn Sie also die Ansicht in übereinstimmende Verzeichnisse stellen, müssen Sie den Namen der Ansicht eingeben, wenn Sie sie im Controller zurückgeben.