Я создаю приложение с помощью angularjs и ASP.NET.Для того, чтобы мои угловые сервисы могли отправлять запросы, мне нужно составить список шаблонов URL с учетом списка контроллеров ASP.NET и действий, которые я затем могу отправить клиенту.
Вид результата, который яищу что-то вроде:
[RoutePrefix("my-controller")]
public class MyController : ControllerBase
{
[Route("my-action/{arg1}/{arg2}")]
public ActionResult MyAction(int arg1, string arg2) {
// ...
}
}
// Elsewhere in my code
GetRouteTemplate("MyController", "MyAction") // => "my-controller/my-action/{arg1}/{arg2}"
Я бы предпочел не кодировать их жестко в интерфейс, так как любое изменение в маршрутизации нарушило бы угловой код, поэтому яЯ искал способ их генерирования.
Моя первая попытка - использовать отражение, чтобы получить все методы действия, а затем вызвать Url.Action, чтобы получить URL-адреса.Я поместил это в свой базовый класс контроллера:
protected Dictionary<String, String> GetUrlTemplates()
{
var controllerName = this
.GetType()
.Name;
var actionNames = this
.GetType()
.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)
.Where(m => !m.IsDefined(typeof(NonActionAttribute), false))
.Select(m => m.Name)
.Distinct()
.ToList();
return actionNames
.ToDictionary(
actionName => actionName,
actionName => Url.Action(actionName, controllerName));
}
Это нормально для любых действий без аргументов, но в противном случае не удается вернуть правильный маршрут.
Моя следующая попытка былачтобы попытаться извлечь шаблоны непосредственно из RouteTable:
protected Dictionary<String, String> GetUrlTemplates()
{
var controllerName = this
.GetType()
.Name;
var actions = this
.GetType()
.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)
.Where(m => !m.IsDefined(typeof(NonActionAttribute), false))
.Select(m => m.Name)
.Distinct()
.ToList();
return RouteTable.Routes
.OfType<LinkGenerationRoute>()
.Select(lgr => new {
url = lgr.Url,
routeAction = lgr.DataTokens["MS_DirectRouteActions"][0]
})
.Where(o => o.routeAction.ControllerDescriptor.ControllerName == controllerName
&& actions.Contains(o.routeAction.ActionName))
.ToDictionary(
o => o.routeAction.ActionName,
o => o.url);
}
Это не работает, потому что LinkGenerationRoute является внутренним классом, поэтому, если нет другого способа получить доступ к этим значениям в таблице маршрутов, это также выглядиткак тупик.
Обе эти попытки немного уродливы и кажутся неправильным подходом, но я не вижу другого способа сделать это.Конечно, генерация шаблонов URL для внешнего интерфейса - довольно распространенная задача - Существует ли «правильный» способ получения шаблонов URL в ASP.NET?Неужели я неправильно подхожу к этой проблеме? Спасибо.