是否可以通过编程方式列出所有控制器的名称及其操作?获取C#中的所有控制器和操作名称
我想为每个控制器和操作实现数据库驱动的安全性。作为一名开发人员,我知道所有的控制器和操作,并且可以将它们添加到数据库表中,但有什么方法可以自动添加它们吗?
是否可以通过编程方式列出所有控制器的名称及其操作?获取C#中的所有控制器和操作名称
我想为每个控制器和操作实现数据库驱动的安全性。作为一名开发人员,我知道所有的控制器和操作,并且可以将它们添加到数据库表中,但有什么方法可以自动添加它们吗?
您可以使用反射来查找当前装配的所有控制器,然后找到自己没有用NonAction
属性修饰的公共方法。
Assembly asm = Assembly.GetExecutingAssembly();
asm.GetTypes()
.Where(type=> typeof(Controller).IsAssignableFrom(type)) //filter controllers
.SelectMany(type => type.GetMethods())
.Where(method => method.IsPublic && ! method.IsDefined(typeof(NonActionAttribute)));
是否为动作方法的动作强制属性? –
@ArsenMkrt好点,我认为方法必须标记为'Action'属性。事实证明,除非使用'NonAction'属性进行修饰,否则所有公共方法都是动作。我已经更新了我的答案。 – dcastro
我们可以进一步了解,所有方法都有返回类型ActionResult的公共方法或从它继承的 –
使用Reflection,枚举所有类型从System.Web.MVC.Controller
继承了组件和过滤器类中,比榜单类型的公共方法作为行动
或者,以削减掉在@dcastro的想法和刚刚得到的控制器:
Assembly.GetExecutingAssembly().GetTypes().Where(type => typeof(Controller).IsAssignableFrom(type))
下面将提取控制器,动作,属性和返回类型:
Assembly asm = Assembly.GetAssembly(typeof(MyWebDll.MvcApplication));
var controlleractionlist = asm.GetTypes()
.Where(type=> typeof(System.Web.Mvc.Controller).IsAssignableFrom(type))
.SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public))
.Where(m => !m.GetCustomAttributes(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), true).Any())
.Select(x => new {Controller = x.DeclaringType.Name, Action = x.Name, ReturnType = x.ReturnType.Name, Attributes = String.Join(",", x.GetCustomAttributes().Select(a => a.GetType().Name.Replace("Attribute",""))) })
.OrderBy(x=>x.Controller).ThenBy(x => x.Action).ToList();
如果您在linqpad中运行此代码,请致电
controlleractionlist.Dump();
将得到以下的输出:
与这个答案,我可以立即得到结果接受的一个很难使用! – hakuna1811
这是什么:'MyWebDll.MvcApplication'是模型类? –
如果存在区域值,是否有办法获取区域值? –
Assembly assembly = Assembly.LoadFrom(sAssemblyFileName)
IEnumerable<Type> types = assembly.GetTypes().Where(type => typeof(Controller).IsAssignableFrom(type)).OrderBy(x => x.Name);
foreach (Type cls in types)
{
list.Add(cls.Name.Replace("Controller", ""));
IEnumerable<MemberInfo> memberInfo = cls.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public).Where(m => !m.GetCustomAttributes(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), true).Any()).OrderBy(x => x.Name);
foreach (MemberInfo method in memberInfo)
{
if (method.ReflectedType.IsPublic && !method.IsDefined(typeof(NonActionAttribute)))
{
list.Add("\t" + method.Name.ToString());
}
}
}
我一直在寻找一种方式来获得区,控制器和行动,对此我设法改变一个小方法,你张贴在这里,所以如果任何人都在寻找一种方式来得到AREA这里是我的丑方法(我保存到XML):
public static void GetMenuXml()
{
var projectName = Assembly.GetExecutingAssembly().FullName.Split(',')[0];
Assembly asm = Assembly.GetAssembly(typeof(MvcApplication));
var model = asm.GetTypes().
SelectMany(t => t.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public))
.Where(d => d.ReturnType.Name == "ActionResult").Select(n => new MyMenuModel()
{
Controller = n.DeclaringType?.Name.Replace("Controller", ""),
Action = n.Name,
ReturnType = n.ReturnType.Name,
Attributes = string.Join(",", n.GetCustomAttributes().Select(a => a.GetType().Name.Replace("Attribute", ""))),
Area = n.DeclaringType.Namespace.ToString().Replace(projectName + ".", "").Replace("Areas.", "").Replace(".Controllers", "").Replace("Controllers", "")
});
SaveData(model.ToList());
}
编辑:
//assuming that the namespace is ProjectName.Areas.Admin.Controllers
Area=n.DeclaringType.Namespace.Split('.').Reverse().Skip(1).First()
我组合了你的代码和这个字符串扩展名:http://stackoverflow.com/a/17253735/453142来获取该区域。所以你可以得到这样的区域:Area = n.DeclaringType.Namespace.ToString()。Substring(“Areas。”,“.Controllers”) 你需要更新扩展以返回string.empty而不是例外,它是。这是一个不太丑陋的=) –
相关:http://stackoverflow.com/questions/11300327/how-can-i-get-the-list-of-all-actions-of-mvc-controller-by-传递 - controllernam – Nathan