2012-07-02 6 views
12

Jak mogę uzyskać listę wszystkich działań kontrolera? Szukam, ale nie mogę znaleźć przykładu/odpowiedzi. Widzę przykład zalecany za pomocą refleksji, ale nie wiem jak.Jak mogę uzyskać listę wszystkich działań kontrolera MVC, przekazując nazwę ControllerName?

Oto co próbuję zrobić:

public List<string> ActionNames(string controllerName){ 




} 
+0

Zamierzam tu dodać komentarz, ponieważ jest ogólny. Bo to, co próbujesz zrobić (nazwy akcji kontrolera) nie jest sposobem, w jaki należy to zrobić. Może być kilka akcji o tej samej nazwie, niektóre mogą być tylko Ajaxem itd. Itd. Twoje uprawnienia powinny być oparte na innych rzeczach niż działania kontrolera. –

Odpowiedz

21

Nie powiedziano nam, dlaczego trzeba to tylko jedną z możliwości jest użycie refleksji:

public List<string> ActionNames(string controllerName) 
{ 
    var types = 
     from a in AppDomain.CurrentDomain.GetAssemblies() 
     from t in a.GetTypes() 
     where typeof(IController).IsAssignableFrom(t) && 
       string.Equals(controllerName + "Controller", t.Name, StringComparison.OrdinalIgnoreCase) 
     select t; 

    var controllerType = types.FirstOrDefault(); 

    if (controllerType == null) 
    { 
     return Enumerable.Empty<string>().ToList(); 
    } 
    return new ReflectedControllerDescriptor(controllerType) 
     .GetCanonicalActions().Select(x => x.ActionName) 
     .ToList(); 
} 

Oczywiście, jak wiemy odbicie nie jest zbyt szybki, więc jeśli zamierzasz wywoływać tę metodę często, możesz rozważyć ulepszenie jej poprzez buforowanie listy kontrolerów, aby uniknąć pobierania za każdym razem, a nawet memoizing metody dla danych parametrów wejściowych.

+0

Dziękujemy! W mojej aplikacji potrzebuję utworzyć stronę uprawnień dla użytkownika admin. Administrator wybrałby nazwę kontrolera z listy rozwijanej, a następnie lista akcji wyświetlałaby się dynamicznie w oparciu o wybraną nazwę kontrolera. Następnie przypisz te wartości do użytkowników/ról. – nannypooh

+0

Wystąpił błąd na "from t in a.GetTypes() - Nie można załadować jednego lub więcej żądanych typów." – nannypooh

+0

Warto zauważyć, że metoda GetCanonicalAction od ReflectedControllerDescriptor zwróci ActionDescriptor dla każdej publicznej metody na kontrolerze, w tym metody, które nie są akcjami. Ignoruje także NonActionAttribute. – rossisdead

0

Lekka korekta do odpowiedzi Darina. Potrzebowałem tej zmiany, aby to działało z kodem kodu, ponieważ działa pod innym zestawem.

public static List<string> GetAllActionNames(string controllerName) 
{ 
    var controllerType = Assembly.Load("YourAssemblyNameHere") 
     .GetTypes() 
     .FirstOrDefault(x => typeof(IController).IsAssignableFrom(x) 
      && x.Name.Equals(controllerName + "Controller", StringComparison.OrdinalIgnoreCase)); 

    if (controllerType == null) 
    { 
     return Enumerable.Empty<string>().ToList(); 
    } 
    return new ReflectedControllerDescriptor(controllerType) 
     .GetCanonicalActions().Select(x => x.ActionName) 
     .ToList(); 
} 
Powiązane problemy