すべてのコントローラーの名前とそのアクションをプログラムでリストすることは可能ですか?
各コントローラーとアクションにデータベース主導のセキュリティを実装したいと考えています。開発者として、私はすべてのコントローラーとアクションを知っており、それらをデータベース テーブルに追加できますが、それらを自動的に追加する方法はありますか?
すべてのコントローラーの名前とそのアクションをプログラムでリストすることは可能ですか?
各コントローラーとアクションにデータベース主導のセキュリティを実装したいと考えています。開発者として、私はすべてのコントローラーとアクションを知っており、それらをデータベース テーブルに追加できますが、それらを自動的に追加する方法はありますか?
リフレクションを使用して、現在のアセンブリ内のすべてのコントローラーを検索し、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)));
私は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()
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());
}
}
}
@デカストロの答えは良いです。このフィルターを追加して、開発者によって宣言されたパブリック アクションのみを返します。
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);
リフレクションを使用し、アセンブリ内のすべての型を列挙し、から継承されたクラスをフィルター処理して System.Web.MVC.Controller
、この型のパブリック メソッドをアクションとしてリストします。
または、@dcastro のアイデアを削ってコントローラーを取得するには:
Assembly.GetExecutingAssembly()
.GetTypes()
.Where(type => typeof(Controller).IsAssignableFrom(type))