반응형
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)));
다음은 컨트롤러, 작업, 속성 및 반환 유형을 추출합니다.
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();
다음 출력이 표시됩니다.
저는 Area, Controller 및 Action을 얻는 방법을 찾고 있었으며 여기에 게시하는 방법을 약간 변경하여 여기에 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()
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 result = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(type => typeof(ApiController).IsAssignableFrom(type))
.SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public))
.Where(m => !m.GetCustomAttributes(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), true).Any())
.GroupBy(x => x.DeclaringType.Name)
.Select(x => new { Controller = x.Key, Actions = x.Select(s => s.Name).ToList() })
.ToList();
이 유형의 공용 메서드를 작업으로 나열하는 것보다 Reflection을 사용 하고 어셈블리 내의 모든 유형을 열거하고에서 상속 된 클래스를 필터링합니다.System.Web.MVC.Controller
@decastro 대답이 좋습니다. 이 필터를 추가하여 개발자가 선언 한 공개 작업 만 반환합니다.
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);
또는 @dcastro의 아이디어에서 벗어나 컨트롤러를 얻으려면 :
Assembly.GetExecutingAssembly()
.GetTypes()
.Where(type => typeof(Controller).IsAssignableFrom(type))
참조 URL : https://stackoverflow.com/questions/21583278/getting-all-controllers-and-actions-names-in-c-sharp
반응형
'developer tip' 카테고리의 다른 글
저장 프로 시저의 출력을 SQL Server의 변수로 반환하는 방법 (0) | 2021.01.06 |
---|---|
코드 서명 ID 란 무엇입니까? (0) | 2021.01.06 |
Python : ( "hello"는 "hello")가 True로 평가되는 이유는 무엇입니까? (0) | 2021.01.05 |
현재 선택한 항목을 다시 선택할 때 Android Spinner에서 이벤트를 받으려면 어떻게해야합니까? (0) | 2021.01.05 |
MySQL의 Case 문 (0) | 2021.01.05 |