SPA роутер в ASP.NET Core Web API?

Привет!
Кейс следующий:
Eсть два проекта - ASP.NET Core Web API (далее Server) и Angular 5 (далее Client). Client умеет билдится в папку wwwroot, чтобы потом можно было запустить в продакшен только один проект Server и все будет работать. Роутер использую от Angular. После сборки в папку wwwroot дальнейшая навигация внутри приложения работает исправно.
Например:
  1. Юзер зашел на localhost:5000
  2. Юзер переходит на localhost:5000/about используя кнопку в навигационном меню
  3. Юзеру отрисовывается страничка About

И вроде бы все хорошо, но... Если сделать рефреш на адресе localhost:5000/about вылетает ошибка 404. Я примерно представляю, почему так происходит (на сервере просто нет страницы about.html), но не знаю, как это пофиксить.

Настройки Startup.cs:
public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(o => o.AddPolicy("Base", builder =>
            {
                builder
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .WithOrigins("http://localhost:4200");
            }));

            services.AddSignalR();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseDefaultFiles();
            app.UseStaticFiles();

            app.UseCors("Base");

            app.UseSignalR(routes =>
            {
                routes.MapHub<ChatHub>("chat");
            });
        }
    }
  • Вопрос задан
  • 1350 просмотров
Решения вопроса 1
Я с такой проблемой столкнулся когда делал первый SPA.

Вот решения:
1) Установить url rewrite на IIS
	http://stackoverflow.com/questions/35319942/url-rewrite-does-not-install-on-windows-10-iis-10
2) How do I configure IIS for URL Rewriting an AngularJS application in HTML5 mode?
	http://stackoverflow.com/questions/12614072/how-do-i-configure-iis-for-url-rewriting-an-angularjs-application-in-html5-mode
	https://www.youtube.com/watch?v=KprM27YP89Q&list=PL6n9fhu94yhWKHkcL7RJmmXyxkuFB3KSl&index=29
3) 
	3.0 Сделать точку входа с префиксом, например /app/
		Добавить в <head>:
		<base href="/app/" />
		На всех ссылках href тоже добавить /app/, или можно этого не делать и когда в href="movies/add" путь не начинается со слеша, то /app/ добавляется автоматически из <base .. />
		, в MVC route добавить первым маршрут:
		routes.MapRoute(
	                name: "Angular",
	                url: "app/{*anything}",
	                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
	            );
		Это позволит на все обращения site/app/ всегда отдавать /Home/Index - в котором находится точка в хода в приложение.
		Таким образом мы никогда не выйдем из приложения, а все другие ссылки должны быть без /app/.
		Ангуляр уже сам разрулит что там отображать исходя из $location.
				
	3.1 Добавить в web.config правила
		<system.webServer>
			<rewrite>
			  <rules>
				<rule name="AngularJS Routes" stopProcessing="true">
				  <match url=".*" />
				  <conditions logicalGrouping="MatchAll">
					<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
					<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
					<add input="{REQUEST_URI}" pattern="^/(bundles)" negate="true" />
					<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
				  </conditions>
				  <action type="Rewrite" url="/" />
				</rule>
			  </rules>
			</rewrite>
		</system.webServer>
	3.2 Использовать OWIN Middleware который будет это делать C# кодом. OWIN middleware to support html5 routing.
	3.3 Использовать свой mvc route provider.
	3.4 Another way to use ASP.NET MVC and add to RouteConfig.cs: routes.MapRoute(name: "Default", url: "{*anything}", defaults: new { controller = "Home", action = "Index", } ); and your HomeController Index just returns File("~/index-anyhinghere.html", "text/html"); Then your app becomes IIS independent


Каждый номер решения - самостоятельный, делать несколько сразу не нужно.
Использую 3.0
Удобно и просто.

Все популярные SPA сайты просто юзают '#', что бы поддерживать старые браузеры.

Фишка SPA в том что бы не перезагружать страницу. Браузер при изменении URL на самом деле стоит на месте, на Index/Home. Ангуляр своими силами через Ajax дергает кусочки HTML и отображает на одной и той же странице - старое стер, новое добавил.

Если нажать F5, то все состояние Javascript будет потеряно, для сохранения данных между F5 подойдет local/session storage.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы