如何解决如何仅路由特定路径,否则路由默认/静态文件
我有一个作为ASP.NET MVC Core应用程序运行的CMS,我想要这样做:
- 对于
/api/
(或/api/*
)和/或/admin/
(或/admin/*
),它会拦截链接并使用其MVC控制器正确路由 - 否则,请使用静态文件(由
index.html
应用管理vue.js
的应用及其内部路由)。
基本用法:如果键入/admin
,请运行ASP.MVC应用程序;如果键入/
(或其他任何变量,如/pages/text
),请调用index.html
vuejs
路由将起作用的地方。
我该怎么办? 试过这个:
public void Configure(IApplicationBuilder app,IHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseDefaultFiles(); // load index.html as default page
app.UseStaticFiles();
app.UseOrchardCore();
}
但是它仅适用于/
,/api/*
和/admin/*
。如果我键入/pages/text
,它将触发ASP.MVC控制器并明显返回错误(而不是vuejs app
路由)。
解决方法
您可以编写一个中间件来处理所有404响应,然后覆盖您的请求路径:
public class ReturnDefaultMiddleware
{
private readonly RequestDelegate _next;
public ReturnDefaultMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
await _next(context);
// If controller was found,return the actual response
if(context.Response.HasStarted || context.Response.StatusCode != (int) HttpStatusCode.NotFound)
return;
// Rewrite the request to request index.html
context.Request.Path = "/index.html";
// Rerun the rest of the request pipeline
await _next(context);
}
}
这将照常执行您的请求管道。如果管道由于未找到可以处理路由的控制器而以404响应,则该请求将被覆盖。
再次运行await _next(context)
,将重新处理整个管道,但对于新的index.html
路由。
只需添加新的中间件,即可运行其他任何东西:
public void Configure(IApplicationBuilder app,IHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// Add custom middleware here
app.UseMiddleware<ReturnDefaultMiddleware>();
app.UseDefaultFiles(); // load index.html as default page
app.UseStaticFiles();
app.UseOrchardCore();
}
编辑 我不认识到API应该回答的特定路线。如果只想在某些特定路由上运行MVC请求管道,则可以覆盖所有其他路由的路径:
app.UseWhen(ctx => !ctx.Request.Path.StartsWithSegments("/api") && !ctx.Request.Path.StartsWithSegments("/admin"),builder =>
{
builder.UseMiddleware<ReturnDefaultMiddleware>();
});
这会将中间件附加到所有不以路径/ admin或/ api开头的请求。 中间件将像这样简单:
public class ReturnDefaultMiddleware
{
private readonly RequestDelegate _next;
public ReturnDefaultMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
// Rewrite the request to request index.html
context.Request.Path = "/index.html";
// Rerun the request pipeline
await _next(context);
}
}
请注意,index.html中的相对链接不适用于此解决方案。您可以考虑覆盖特定文件结尾的路径或中间件内部的路径。
,我在启用身份验证的Blazor WebAssembly托管应用程序中执行了类似的操作。
在我在邮递员中致电/api/{controller}
的情况下,我收到的是HTML而不是json。
我通过添加以下内容解决了这个问题:
app.UseEndpoints(endpoints =>
{
...
endpoints.Map("api/{**slug}",HandleApiFallback);
endpoints.MapFallbackToFile("{**slug}","index.html");
});
private Task HandleApiFallback(HttpContext context)
{
context.Response.StatusCode = StatusCodes.Status404NotFound;
return Task.FromResult(0);
}
我认为它也可以适应您的情况。
另一种可行的方法是:
// In production,the Vue files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
app.UseSpaStaticFiles();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",pattern: "{controller}/{action=Index}/{id?}");
if (env.IsDevelopment())
{
endpoints.MapToVueCliProxy(
"{*path}",new SpaOptions { SourcePath = "ClientApp" },npmScript: "serve",regex: "Compiled successfully");
}
// Add MapRazorPages if the app uses Razor Pages. Since Endpoint Routing includes support for many frameworks,adding Razor Pages is now opt -in.
endpoints.MapRazorPages();
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
});
您的Vue应用应位于名为“ ClientApp”的目录内。请查看此sample。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。