Может быть, я должен сделать резервную копию и расширить область видимости, прежде чем погрузиться в заглавный вопрос ...
В настоящее время я пишу веб-приложение в ASP.NET MVC 1.0 (хотя у меня установлен MVC 2.0на моем ПК, поэтому я не ограничен до 1.0) - я начал со стандартного проекта MVC, который имеет базовое «Welcome to ASP.NET MVC» и отображает вкладки [Home] и [About]в правом верхнем углу.Довольно стандартный, верно?
Я добавил 4 новых класса Controller, назовем их «Астроном», «Биолог», «Химик» и «Физик».К каждому новому классу контроллера прикреплен атрибут [Authorize].
Например, для BiologistController.cs
[Authorize(Roles = "Biologist,Admin")]
public class BiologistController : Controller
{
public ActionResult Index() { return View(); }
}
Эти теги [Authorize] естественным образом ограничивают, какой пользователь может получить доступ к различным контроллерам в зависимости от ролей, но я хочу динамически создать меню навверху моего сайта на странице Site.Master, основанной на ролях, в которых участвует пользователь.Так, например, если бы «JoeUser» был членом ролей «Астроном» и «Физик», в меню навигации было бы сказано:
[Домой] [Астроном] [Физик] [О нас]
И, естественно, в не будет список ссылок на страницу индекса контроллера "Биолог" или "Химик".
Или, если "JohnAdmin" был членом Role "Admin ", ссылки на все 4 контроллера будут отображаться на панели навигации.
Хорошо, теперь вы поняли идею ... Теперь для реального вопроса ...
Начиная с ответа от этой темы StackOverflow о динамическом менюВстраивая в ASP.NET , я пытаюсь понять, как бы полностью реализовать это.
В ответе предлагается расширить класс Controller (назовите его «ExtController»), а затем каждый новыйВсе, что унаследовано от ControlController от ExtController.
Я пришел к выводу, что мне нужно использовать Reflection в этом конструкторе ExtController, чтобы определить, к каким классам и методам прикреплены атрибуты [Authorize] для определения ролей.Затем, используя статический словарь, сохраните роли и контроллеры / методы в парах ключ-значение.
Я представляю это примерно так:
public class ExtController : Controller
{
protected static Dictionary<Type,List<string>> ControllerRolesDictionary;
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
// build list of menu items based on user's permissions, and add it to ViewData
IEnumerable<MenuItem> menu = BuildMenu();
ViewData["Menu"] = menu;
}
private IEnumerable<MenuItem> BuildMenu()
{
// Code to build a menu
SomeRoleProvider rp = new SomeRoleProvider();
foreach (var role in rp.GetRolesForUser(HttpContext.User.Identity.Name))
{
}
}
public ExtController()
{
// Use this.GetType() to determine if this Controller is already in the Dictionary
if (!ControllerRolesDictionary.ContainsKey(this.GetType()))
{
// If not, use Reflection to add List of Roles to Dictionary
// associating with Controller
}
}
}
Это выполнимо?Если это так, как мне выполнить Reflection в конструкторе ExtController, чтобы обнаружить атрибут [Authorize] и соответствующие роли (если есть)
ТАКЖЕ!Не стесняйтесь выходить за рамки этого вопроса и предлагать альтернативный способ решения этой проблемы «Динамическое меню Site.Master на основе ролей».Я первый, кто признает, что это не лучший подход.