с отражением я успешно получаю список методов контроллера.
чтобы получить аргументы возвращаемого типа метода, я использую *.GenericTypeArguments следующим образом:
Some MethodInfo x.GenericTypeArguments.Select(a => a.Name);
При таком методе:
public async Task<ApiResult> SomeMethod();
я получаю хороший результат: "ApiResult"
Но когда возвращаемый тип имеет список вроде:
public async Task<List<string>> SomeMethod();
Я получаю -> Task,List,System.Linq.Enumerable+SelectArrayIterator`2[System.Type,System.String] вместо Задача,Список,Строка
то же для
public async Task<Dictionary<string,string>> SomeMethod();
ожидаемая задача,словарь,строка,строка
получено Task,Dictionary,System.Linq.Enumerable+SelectArrayIterator`2[System.Type,System.String]
here the exact code I use:
Assembly asm = Assembly.GetExecutingAssembly();
var controllerMethodlist = asm.GetTypes()
.Where(type => typeof(ControllerBase).IsAssignableFrom(type))
.SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public))
.Where(m => !m.GetCustomAttributes(typeof(CompilerGeneratedAttribute), true).Any())
.Select(x => new
{
Controller = x.DeclaringType.Name,
Action = x.Name + "(" + String.Join(",", x.GetParameters().Select(p => p.Name)) + ")",
ReturnType = x.ReturnType.Name.LastIndexOf('`') == -1 ? x.ReturnType.Name : (x.ReturnType.Name.Substring(0, x.ReturnType.Name.LastIndexOf('`')) + "<" +
String.Join(",", x.ReturnType.GenericTypeArguments.Select(a => a.Name.LastIndexOf('`') == -1 ? a.Name : a.Name.Substring(0, a.Name.LastIndexOf('`')) +
(a.GenericTypeArguments.Count() > 0 ? "<" + String.Join(",", a.GenericTypeArguments.Select(b => b.Name.LastIndexOf('`') == -1 ? b.Name : b.Name.Substring(0, b.Name.LastIndexOf('`')) +
(b.GenericTypeArguments.Count() > 0 ? "<" + String.Join(",", b.GenericTypeArguments.Select(c => c.Name.LastIndexOf('`') == -1 ? c.Name : c.Name.Substring(0, c.Name.LastIndexOf('`'))) + ">") : ""))) + ">" : ""))) + ">")
,
Attributes = String.Join(",", x.GetCustomAttributes().Select(a => a.GetType().Name.Replace("Attribute", "") + "|" +
(
a.GetType() == typeof(HttpGetAttribute) ? ((HttpGetAttribute)a).Template :
a.GetType() == typeof(HttpPostAttribute) ? ((HttpPostAttribute)a).Template :
a.GetType() == typeof(HttpDeleteAttribute) ? ((HttpDeleteAttribute)a).Template :
a.GetType() == typeof(HttpPutAttribute) ? ((HttpPutAttribute)a).Template :
a.GetType() == typeof(CrudControllerAuthAttribute) ? ((CrudControllerAuthAttribute)a).CrudAuth.ToString() :
"*"
)))
})
.OrderBy(x => x.Controller).ThenBy(x => x.Action).ToList();
Проблема в свойстве "ReturnType":
У меня есть следующие методы:
public async Task<IActionResult> ConfirmEmail(parameters)
и как ResultType я получаю правильное значение
Task<IActionResult>
Но следующим методом:
public async Task<ApiResultT<Dictionary<string,string>>> GetCsvDictionaryForTemplate(CsvBase64)
в качестве ResultType я получаю
`Task<ApiResultT<Dictionary<System.Linq.Enumerable+SelectArrayIterator`2[System.Type,System.String]>>>`
вместо
Task<ApiResultT<Dictionary<string,string>>>
или следующим методом:
public async Task<ApiResultT<List<CsvClassesDto>>> GetCsvClasses()
Я получаю:
Task<ApiResultT<List<System.Linq.Enumerable+SelectArrayIterator`2[System.Type,System.String]>>>
Вместо:
Task<ApiResultT<List<CsvClassesDto>>>
Итак, у меня возникает проблема, когда тип представляет собой список или словарь, поэтому Enumerable.
Надеюсь, я понял
Спасибо за помощь
Пьеркарло
Пожалуйста, покажите минимальный воспроизводимый пример. В классе
MethodInfo
нет свойства с именемGenericTypeArguments
.Можете ли вы опубликовать свой фактический код вместо этого:
Some MethodInfo x.GenericTypeArguments.Select(a => a.Name);
. Непонятно, как вы читаете аргументы универсального типа вложенных (не буквально) универсальных типов, которые определяют возвращаемый тип этих методов. -- Поскольку вы должны прочитать все аргументы каждого типа, покаIsGenericType = true
, возможно, в процедуре что-то не так.