【发布时间】:2020-01-28 14:56:15
【问题描述】:
我正在尝试在后端创建一个带有 ASP.NET 核心的 VueJS SPA
由于dotnet SDK版本3.0.100不再支持Vue,我创建了一个React应用
dotnet new react
并将 ClientApp 替换为 Vue 应用程序
rm -rf ClientApp
vue create frontend
除了一件事,一切都完美无缺
每当我启动应用程序 http://localhost:5000 并单击任何 Vue 路由器链接时,说 http://localhost:5000/about(它有效)但如果我刷新我会得到 预期的 404
无法获取/关于
如果我在浏览器中输入 URL 并直接访问也是如此
值得注意的是,默认的 React 应用程序没有遇到这个问题,我使用 this tool 比较了两个 ASP.NET 应用程序的文件之间的所有内容,发现没有差异
现在 Vue 路由器通过 Javascript 处理路由,因为它在幕后使用 #!hash,因此 ASP.NET 路由器尝试将 URL 与不存在的 AboutController@index 匹配,因此 404
研究表明我应该在Startup.cs 中设置一个通配符回退到 SPA 路由器,但我找到的所有答案都是here、here、here、this question、answer here、this question和 this one 正在使用 app.UseMvc() 而我没有启用它,我正在使用 app.UseEndpoints 代替
我也试过搜索 GitHub 但还是一样的results
This Answer 建议我也坚持app.UseEndPoints 和Microsoft migration guide
The Vue Router Documentation 谈到了这个问题,并为 .NET 应用程序提出了一个解决方案,使用 web.config 用于 IIS,就像答案 here 一样,但我在 Linux 机器上运行 Kestrel 服务器,所以这不起作用
这是我的 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 here,以便在我忘记某些内容时轻松重现
我怎样才能达到同样的效果
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
}
]
})
【问题讨论】:
-
嗨,你知道如何解决这个问题吗?
-
@FrodeLillerud 是的,请参阅this repo
标签: asp.net-core vuejs2 single-page-application vue-router