如何将控制器中找不到的Action重定向到同一控制器中的另一个操作?让我们说通过abc.txt
请求文件http://localhost:5000/Link/GetFile/abc.txt
。我的控制器正确地提供该文件。但现在,我需要处理http://localhost:5000/Link/Document/abc
等请求。当然没有任何与Document
相匹配的动作所以我需要在同一个控制器中调用函数Error
(包括来自原始请求的id)。
我尝试用StatusCodePagesWithReExecute
函数解决这个问题,但后来我的File
动作不起作用(每个请求直接转到Error函数)。
我有以下控制器:
public class LinkController : ControllerBase
{
public IActionResult GetFile(string id)
{
return DownloadFile(id);
}
public IActionResult Error(string id)
{
return File("~/index.html", "text/html");
}
private FileResult DownloadFile(string fileName)
{
IFileProvider provider = new PhysicalFileProvider(@mypath);
IFileInfo fileInfo = provider.GetFileInfo(fileName);
var readStream = fileInfo.CreateReadStream();
return File(readStream, "text/plain");
}
}
和启动配置:
app.UseDefaultFiles();
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "application/octet-stream",
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action}/{id?}"
);
});
任何线索如何解决这个问题?问候
只要有404,就可以使用UseStatusCodePages
实现简单的重定向。这就是它的样子:
app.UseStatusCodePages(ctx =>
{
if (ctx.HttpContext.Response.StatusCode == 404)
ctx.HttpContext.Response.Redirect("/Path/To/Your/Action");
return Task.CompletedTask;
});
只需将它添加到UseMvc
上方。
编辑:
对不起,我的第一个答案是不对的。
IRouteCollection router = RouteData.Routers.OfType<IRouteCollection>().First();
有了这个,你可以匹配一个url到控制器动作
private readonly IHttpContextFactory _httpContextFactory;
public HomeController(
IHttpContextFactory httpContextFactory)
{
_httpContextFactory = httpContextFactory;
}
HttpContext context = _httpContextFactory.Create(HttpContext.Features);
context.Request.Path = "/Home/Index";
context.Request.Method = "GET";
var routeContext = new RouteContext(context);
await router.RouteAsync(routeContext);
bool exists = routeContext.Handler != null;
进一步阅读:https://joonasw.net/view/find-out-if-url-matches-action