如何使用C#中的Reflection使用属性查找控制器? (或如何构建动态Site.Master菜单?)
也许在进入标题问题之前我应该备份并扩大范围……
我目前正在ASP.NET MVC 1.0中编写一个Web应用程序(虽然我的PC上安装了MVC 2.0,所以我并不完全限于1.0) – 我已经开始使用标准的MVC项目了基本的“欢迎使用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”是角色“Admin”的成员,则指向所有4个控制器的链接将显示在导航栏中。
好吧,你们大家都有了想法…现在回答真正的问题……
从StackOverflow主题关于ASP.NET中动态菜单构建的答案开始,我试图理解如何完全实现它。
答案建议扩展Controller类(称之为“ExtController”),然后让每个新的WhateverControllerinheritance自ExtController。
我的结论是,我需要在这个ExtController构造函数中使用Reflection来确定哪些类和方法附加了[Authorize]属性来确定角色。 然后使用静态字典,将角色和控制器/方法存储在键值对中。
我想象它是这样的:
public class ExtController : Controller { protected static Dictionary<Type,List> ControllerRolesDictionary; protected override void OnActionExecuted(ActionExecutedContext filterContext) { // build list of menu items based on user's permissions, and add it to ViewData IEnumerable menu = BuildMenu(); ViewData["Menu"] = menu; } private IEnumerable 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 } } }
这可行吗? 如果是这样,我如何在ExtController构造函数中执行Reflection以发现[Authorize]属性和相关角色(如果有的话)
也! 在这个问题上随意超出范围并建议另一种方法来解决这个“基于角色的动态Site.Master菜单”问题。 我是第一个承认这可能不是最佳方法的人。
编辑
经过大量的阅读和实验,我想出了自己的解决方案。 请参阅下面的答案。 任何建设性的反馈/批评欢迎!
我更喜欢链接到我的菜单中的所有内容并创建一个HtmlHelper,它根据[Authorize]属性检查链接是否可访问 。
好的,所以我决定充实我自己的扩展控制器类,就像我最初提出的那样。 这是一个非常基本的版本。 我可以看到各种方法使这更好(进一步扩展,收紧代码等)但我认为我会提供我的基本结果,因为我想有很多其他人想要类似的东西,但可能不希望所有额外的。
public abstract class ExtController : Controller { protected static Dictionary> RolesControllerDictionary; protected override void OnActionExecuted(ActionExecutedContext filterContext) { // build list of menu items based on user's permissions, and add it to ViewData IEnumerable
要使用,只需:
例如:
[Authorize(Roles = "Biologist,Admin")] public class BiologistController : ExtController { public ActionResult Index() { return View(); } }
如果不将“Controller”替换为“ExtController”,则该Controller将没有动态菜单。 (在某些情况下,这可能很有用,我认为…)
在我的Site.Master文件中,我将“菜单”部分更改为如下所示:
就是这样! ?
上述就是C#学习教程:如何使用C#中的Reflection使用属性查找控制器? (或如何构建动态Site.Master菜单?)分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1023563.html