5

Obecnie mam strukturę folderów tak:MVC Obszary Routing - Folder Kontroler z folderu

Area (folder) 
- Toolkit (folder) 
    - Controllers (folder) 
     - AdminController.cs 
    - Views (folder) 
     - Admin (folder) 
      - Privledges (folder) 
       - Create.cshtml 
       - Edit.cshtml 
       - Delete.cshtml 

co przekłada się

/Toolkit/{controller}/{action}/{tool}/{id} 

Czy jest złą praktyką skonfigurować działanie zachowywać przypomina kontroler wyświetlający widok oparty na parametrze {tool} i parametrze {id} przekazanym do działania?

Realizacja co mówię:

private const string FOLDER_PRIVILEGES = "./Privileges/"; 

    public ActionResult Privileges(string tool, string id = "") 
    { 
     dynamic viewModel = null; 
     ToolViews view; // enum for the views 
     // Parse the tool name to get the enum representation of the view requested 
     bool isParsed = Enum.TryParse(tool, out view); 

     if (!isParsed) 
     { 
      return HttpNotFound(); 
     } 

     switch (view) 
     { 
      case ToolViews.Index: 
       viewModel = GetIndexViewModel(); // call a function that gets the VM 
       break; 
      case ToolViews.Edit: 
       viewModel = GetEditViewModelById(int.Parse(id)); // sloppy parse 
       break; 
      default: 
       viewModel = GetIndexViewModel(); 
       break; 
     } 
     // The folder path is needed to reach the correct view, is this bad? 
     // Should I just create a more specific controller even though it would 
     // require making about 15-20 controllers? 
     return View(FOLDER_PRIVILEGES + tool, viewModel); 
    } 

Kiedy piszę widoku, muszę się upewnić, że nazwa ścieżki jest używany do folderu

@Html.ActionLink("Edit", "./Toolkit/Admin/Priveleges/Edit", "Admin", new { id = item.id }) 

Wydaje się, być kiepską praktyką, ponieważ jeśli struktura folderów ulegnie w ogóle zmianie, będzie wymagała wielu czynności konserwacyjnych.

Jednakże, jeśli będę musiał przebić się na kontrolerzy, będzie ich wiele (prawie 20 z dodatkiem w czasie).

Jeśli to, co robię, to zła praktyka, jaki byłby najlepszy sposób obsłużenia trasy wyglądającej tak?

/Toolkit/Admin/Privileges/Edit/1 

Chcę uniknąć w następujący sposób:

/Toolkit/Admin/CreatePrivileges/1 
/Toolkit/Admin/EditPrivileges/1 
/Toolkit/Admin/DeletePrivileges/1 

Proszę dać mi znać, jeśli nie mam żadnego sensu, ponieważ mam problemy ze wprowadzenie tej kwestii do słowa.

+0

Być może jestem nieporozumienie, ale przy użyciu wzorca nie zamierzasz utworzyć oddzielną funkcję, aby zwrócić odpowiedni model widoku w zależności od wyliczenia ToolViews' tak czy inaczej? Cały punkt MVC to konwencja nad konfiguracją. Ponieważ konwencja w MVC jest oddzielną akcją, aby poradzić sobie z każdą oddzielną możliwością, wydaje się, że jest to "najlepsza praktyka", aby przejść do drugiego przykładu. IE:/Toolkit/Admin/CreatePrivileges/1. –

+0

Zdecydowałem, że jeśli chcę strawnego adresu URL, muszę podzielić go na mniejsze kontrolery. Być może trochę irytujące jest posiadanie gromady kontrolerów, ale jest to lepsze niż to, co próbowałem wcześniej zrobić. Zamiast robić/Toolkit/Admin/CreatePrivileges/1 Mam/Toolkit/Privileges/Create/1. Zdałem sobie sprawę, że część/Admin/nie ma znaczenia dla adresu URL, gdy miałem wiele mniejszych kontrolerów. –

+0

Więc myślę, że się zgadzamy? –

Odpowiedz

1

Myślę, że próbujesz zmusić konwencję do MVC, która jest sprzeczna z jej intencją.

Z MVC, twój kontroler jest rzeczownikiem, a twoje działanie jest czasownikiem. Twoje przykłady, trzeba:

  • Toolkit (rzeczownik) - Powierzchnia
    • Admin (? Rzeczownik) - Sub-area? < - to taki, który jest trochę ostry
      • Przywileje (rzeczownik) - Kontroler
        • Tworzenie (czasownik) - Akcja
        • Edit (czasownik) - Akcja
        • Delete (czasownik) - Akcja

Jak widać, jeśli możesz uznać Toolkit + Admin jako obszar + podobszar lub połączyć go w jeden obszar (TookitAdmin), to wróci do pierwotnego celu kontrolerów i działań.

Na podstawie komentarzy, wygląda na to, że zdecydowałeś się pójść tą drogą. Ale chciałem zwrócić uwagę, że wniosek, do którego doszło w sposób rundy, polega na powrocie do korzeni MVC.

Czy na marginesie rozważałeś przeniesienie do MVC4? Jego Web API zapewnia lepszą obsługę RESTful API, co do którego może się wydawać.

+0

Zgadzam się. Byłem niesamowity dzięki użyciu tak wielu kontrolerów. Szczególnie sterowniki z jednym działaniem. Jednak po przetestowaniu tego podejścia nie było tak źle, gdy znajduje się w jego własnym obszarze. Użyłem Web API i to właśnie to sprawia, że ​​chcę mieć bardziej RESTNY URL. Niestety, ten projekt na razie utknął w MVC3. –

1

Nie jest to odpowiedź na pierwotne pytanie, ale OP poprosił o próbę ograniczenia Enum, zamiast sprawdzać wyliczenie w każdym działaniu. tj:

// Parse the tool name to get the enum representation of the view requested 
bool isParsed = Enum.TryParse(tool, out view); 

if (!isParsed) 
{ 
    return HttpNotFound(); 
} 

Zamiast zaakceptować wartość enum (narzędzie, w tym przypadku) jako ciąg, można wymusić wartość do swego działania już oddane jako właściwego wyliczenia. Dodatkową korzyścią jest to, że środowisko MVC zadba o zwrot prawidłowej odpowiedzi (HttpNotFound) w tym przypadku.

To jest twoja metoda ograniczenia. Akceptuje każdy rodzaj Enum. Nie ma potrzeby tworzenia oddzielnego ograniczenia dla każdego Enum.

public class EnumConstraint<T> : IRouteConstraint where T : struct 
{ 
    private readonly HashSet<string> enumNames; 
    public EnumConstraint() 
    { 
     string[] names = Enum.GetNames(typeof(T)); 
     this.enumNames = new HashSet<string>(from name in names select name.ToLowerInvariant()); 
    } 

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     return this.enumNames.Contains(values[parameterName].ToString().ToLowerInvariant()); 
    } 

} 

Następnie w metodzie RegisterRoutes (MVC4) lub widoku Global.asax.cs (MVC3), wystarczy zarejestrować swoją trasę tak:

routes.MapRoute(
    url: "/Toolkit/Admin/{Action}/{id}", 
    constraints: new { Action = new EnumConstraint<ToolViews>(), id = @"\d+" } 
); 

Dodałem też presję na numer id parametr, aby zaoszczędzić również na konieczności przeanalizowania tego.

Daj mi znać, jak to działa.

+0

Jest to niezwykle pomocne. Dziękuję Ci bardzo! –

+0

@David - Cieszę się, że mogę Ci pomóc –