Как обрабатывать маршруты с помощью VueJS в ядре ASP.NET с использованием конечных точек? - PullRequest
1 голос
/ 28 сентября 2019

Пытаюсь создать VueJS SPA с ядром ASP.NET в бэкэнде

Поскольку dotnet SDK версия 3.0.100 больше не поддерживает Vue, я создал приложение React

dotnet new react

и поменял ClientApp с приложением Vue

rm -rf ClientApp
vue create frontend

Все отлично работает, кроме 1 вещи

Всякий раз, когда я запускаю приложение http://localhost:5000 и нажимаю на любой Vue Routerссылка, скажем, http://localhost:5000/about (это работает), но если я обновляю, я получаю ожидаемый 404

Невозможно получить / о

То же самое происходит, если я набрал URL-адрес в браузере и получил прямой доступ

Стоит отметить, что приложение React по умолчанию не сталкивается с этой проблемой, я сравнил все между файлами двух приложений ASP.NET, используя этот инструмент и не обнаружил различий

Теперь Vue Router обрабатывает маршруты с помощью Javascript, потому что он использует хэш #! за кулисами, поэтому маршрутизатор ASP.NET пытается сопоставить URL с индексом AboutController @, которыйне существует, следовательно, 404

Research reЯ заверил, что я должен установить резервный символ подстановки для маршрутизатора SPA в Startup.cs, но все ответы, которые я нашел здесь , здесь , здесь , на этот вопрос , ответьте здесь , на этот вопрос и этот использует app.UseMvc(), и у меня его нет, я использую app.UseEndpoints вместо

Я также пытался искать в GitHub, но те же результаты

В этом ответе рекомендует придерживаться app.UseEndPoints и миграции Microsoftруководство тоже

Документация Vue Router рассказывает об этой самой проблеме и предлагает решение для приложений .NET, использующее web.config для IIS, например, ответ здесь но я запускаю сервер Kestrel на машине с Linux, так что это не дает никакого эффекта

Вот мой Startup.cs файл

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer;

namespace spa
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {

            services.AddControllersWithViews();

            // In production, the Vue files will be served from this directory
            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "frontend/dist";
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseSpaStaticFiles();

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller}/{action=Index}/{id?}");
            });

            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "frontend";

                if (env.IsDevelopment())
                {
                    spa.UseReactDevelopmentServer(npmScript: "serve:bs");
                }
            });
        }
    }
}

Я переместил это приложение в GitHub здесь , чтобы сделатьего легко воспроизвести на тот случай, если я что-то забыл

Как я могу добиться того же эффекта от этого

app.UseMvc(routes =>
{
  routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
  routes.MapRoute("spa-fallback", "{*anything}", new { controller = "Home", action = "Index" });
});

, используя app.UseEndpoints?


На всякий случай, это уместно, вот мой маршрутизатор Vue

import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
import NotFound from './views/NotFound.vue'

Vue.use(Router)

export default new Router({
    mode: 'history',
    base: process.env.BASE_URL,
    routes: [{
            path: '/',
            name: 'home',
            component: Home
        },
        {
            path: '/about',
            name: 'about',
            // route level code-splitting
            // this generates a separate chunk (about.[hash].js) for this route
            // which is lazy-loaded when the route is visited.
            component: () => import( /* webpackChunkName: "about" */ './views/About.vue')
        },
        {
            path: '/forecast',
            name: 'forecast',
            component: () => import( /* webpackChunkName: "forecast" */ './views/Forecast.vue')
        },
        {
            path: '*',
            component: NotFound
        }
    ]
})
...