在C#中获取所有控制器和操作名称
是否有可能以编程方式列出所有控制器的名称和他们的行动?
我想为每个控制器和操作实现数据库驱动的安全性。 作为开发人员,我知道所有的控制器和操作,并可以将它们添加到数据库表,但有什么办法自动添加它们?
您可以使用reflection来查找当前程序集中的所有控制器,然后查找未使用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)));
以下将提取控制器,操作,属性和返回types:
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();
你会得到以下输出:
我正在寻找一种方法来获得区域,控制器和行动,为此,我设法改变了一些你在这里发布的方法,所以如果有人正在寻找一种方法来获得 区域在这里是我丑陋的方法(我保存一个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()); }
使用reflection ,枚举程序集内的所有types,并过滤从System.Web.MVC.Controller
inheritance的类,而不是将这些types的公共方法列为动作
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()); } } }
或者,减less@dcastro的想法,只是得到控制器:
Assembly.GetExecutingAssembly().GetTypes().Where(type => typeof(Controller).IsAssignableFrom(type))