ASP.NET MVC 5 с угловой 7; как внедрить виртуальный путь веб-приложения в угловые маршруты?
Извините за длину, мой первый вопрос здесь о переполнении стека. Я провожу немного времени, чтобы познакомить вас с границами моей проблемы.
У меня есть веб-приложение ASP.NET, которое начиналось как приложение, использующее исключительно веб-формы. Чтобы воспользоваться возможностями, предоставляемыми такими современными веб-технологиями, как Angular, я добавил ASP.NET MVC в это приложение. Веб-формы и страницы бритвы MVC теперь работают бок о бок. Замечательно!
Я добавил MVC к миксу, потому что обнаружил, что Angular легче использовать на странице бритвы MVC, чем на веб-формах. Во всяком случае, это мой опыт.
Идея состоит в том, чтобы создать в моем приложении один маршрут, который запускает бритвенную веб-страницу, на которой захватывает Angular. Естественно, две технологии были предназначены для вмешательства друг в друга в отношении маршрутизации внутри приложения.
Итак, мое приложение теперь имеет контроллер MVC, который я назвал SpaController. Метод действия внутри этого называется Index. Довольно стандартный пока.
После долгих исследований и метода проб и ошибок я нашел решение, которое работает: всякий раз, когда я перехожу к этому URI: "/spa" или "/spa/index", MVC отображает страницу бритвы. называется "~/Views/Spa/Index.vbhtml". Вот мои маршруты MVC:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}")
routes.MapRoute(
name := "SpaRoute",
url := "Spa",
defaults := New With {.Controller = "Spa", .Action = "Index", .Id = UrlParameter.Optional})
routes.MapRoute(
name := "SpaIndexRoute",
url := "Spa/Index",
defaults := New With {.Controller = "Spa", .Action = "Index", .Id = UrlParameter.Optional})
routes.MapRoute(
name := "AppRoute",
url := "app/dashboard",
defaults := New With {.Controller = "Spa", .Action = "Index", .Id = UrlParameter.Optional})
routes.MapRoute(
name := "AngularAnyRoute",
url := "*{url}",
defaults := New With {.Controller = "Spa", .Action = "Index", .Id = UrlParameter.Optional})
Как вы можете видеть, я определил отдельный маршрут для использования с или без имени метода действия, а также некоторые маршруты MVC для обработки навигации к угловым маршрутам в конце.
Мне пришлось добавить угловые маршруты, потому что я хочу, чтобы пользователь мог обновлять страницу в браузере после перехода к любому угловому маршруту. Обновление, как вы все знаете, выполняет полное обновление на стороне сервера. Поскольку URL-адрес изменяется с маршрута MVC "/Spa/Index" на "/app/dashboard/" после загрузки углового приложения, я должен убедиться, что приложение не ищет контроллер MVC с именем AppController с действием метод под названием "Панель инструментов" (который не существует). Вместо этого я хочу перенаправить пользователя обратно в SpaController, который снова обслуживает угловое приложение.
В случае, если вам интересно: на странице _Layout.vbhtml я установил базовый URL-адрес "/VirtualFolder/app". Это сообщает угловому приложению, что его навигация начинается с этой части URI.
<head>
<base href="@(Url.Content("~/app"))" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Application with MVC and Angular</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
Теперь мы рассмотрим мою проблему: у моего углового приложения в качестве корня есть маршрут панели мониторинга. Поэтому я определил маршрут с помощью пути, подобного "приборной панели". Однако, поскольку MVC находится в миксе, мне пришлось добавить несколько маршрутов MVC в угловую маршрутизацию и выполнить действие перенаправления на этих маршрутах, которое перенаправляет любой трафик на маршрут панели мониторинга.
Моя проблема заключается в том, что эти маршруты должны содержать имя виртуальной папки моего веб-приложения. Мое приложение работает под управлением IIS, и URI становится примерно таким:
https://localhost/VirtualFolder/
Поскольку я развертываю свое веб-приложение для разных клиентов, а имя виртуальной папки различается для каждого клиента, я бы хотел избежать жесткого кодирования угловых маршрутов для каждого клиента. Я хотел бы, чтобы в эти маршруты было введено имя виртуальной папки моего приложения.
Вот мои угловые маршруты до сих пор. Вы можете увидеть имя виртуальной папки там.
{
path: 'dashboard',
component: DashboardComponent
},
{
path: 'VirtualFolder/Spa',
redirectTo: 'dashboard'
},
{
path: 'VirtualFolder/spa',
redirectTo: 'dashboard'
},
{
path: 'VirtualFolder/Spa/Index',
redirectTo: 'dashboard'
},
{
path: 'VirtualFolder/spa/index',
redirectTo: 'dashboard'
},
{
path: 'VirtualFolder/app',
redirectTo: 'dashboard'
},
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
}
Я нашел статью, описывающую, как можно получать маршруты через службу (возвращенную как json) и сбрасывать угловые маршруты приложения перед загрузкой AppComponent:
Тем не менее, я хочу знать, знает ли кто-нибудь из вас о решении, включающем меньшее количество кода.
Я надеялся, что MVC будет легко вставить имя виртуальной папки в файл JavaScript при загрузке страницы бритвы, но это не так просто (пожалуйста, исправьте меня, если я ошибаюсь),
Другому парню удалось передать значение в AppComponent, указав свойство в главном теге приложения, например так:
<app-root virtualFolderPath="VirtualFolder"><app-root>
Однако, хотя такое значение действительно передается в конструктор компонента, который загружается с помощью angular (обычно AppComponent), мне нужно изменить значения массива маршрутов внутри app-routing.module.ts, а также Следует понимать, что модуль маршрутизации уже инициализирован, когда код внутри AppComponent может быть выполнен. Если бы я только мог передать значение в модуль маршрутизации аналогичным образом...
Надеюсь, что у кого-то есть совет относительно того, что он считает лучшим решением для этого. Я был бы очень признателен. Надеюсь, кто-то столкнулся с такой же проблемой, как и я сейчас.