80

すべてのコントローラーの名前とそのアクションをプログラムでリストすることは可能ですか?

各コントローラーとアクションにデータベース主導のセキュリティを実装したいと考えています。開発者として、私はすべてのコントローラーとアクションを知っており、それらをデータベース テーブルに追加できますが、それらを自動的に追加する方法はありますか?

4

11 に答える 11

89

リフレクションを使用して、現在のアセンブリ内のすべてのコントローラーを検索し、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)));
于 2014-02-05T16:52:09.277 に答える
8

私はArea、Controller、およびActionを取得 する方法を探していました。このために、ここに投稿したメソッドを少し変更することができました。 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()
于 2016-04-06T07:00:40.500 に答える
3
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());
           }
      }
}
于 2015-10-14T05:35:33.770 に答える
1

@デカストロの答えは良いです。このフィルターを追加して、開発者によって宣言されたパブリック アクションのみを返します。

        var asm = Assembly.GetExecutingAssembly();
        var methods = asm.GetTypes()
            .Where(type => typeof(Controller)
                .IsAssignableFrom(type))
            .SelectMany(type => type.GetMethods())
            .Where(method => method.IsPublic 
                && !method.IsDefined(typeof(NonActionAttribute))
                && (
                    method.ReturnType==typeof(ActionResult) ||
                    method.ReturnType == typeof(Task<ActionResult>) ||
                    method.ReturnType == typeof(String) ||
                    //method.ReturnType == typeof(IHttpResult) ||
                    )
                )
            .Select(m=>m.Name);
于 2018-07-06T14:10:05.230 に答える
1

リフレクションを使用し、アセンブリ内のすべての型を列挙し、から継承されたクラスをフィルター処理して System.Web.MVC.Controller、この型のパブリック メソッドをアクションとしてリストします。

于 2014-02-05T16:50:22.100 に答える
0

または、@dcastro のアイデアを削ってコントローラーを取得するには:

Assembly.GetExecutingAssembly()
.GetTypes()
.Where(type => typeof(Controller).IsAssignableFrom(type))
于 2014-08-04T20:50:01.083 に答える