如何将控制器中未找到的动作重定向到同一控制器中的另一个动作?假设通过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?}"
);
});
有什么线索可以解决这个问题吗? 问候
答案 0 :(得分:2)
只要有404,您就可以使用UseStatusCodePages
来实现简单的重定向。如下所示:
app.UseStatusCodePages(ctx =>
{
if (ctx.HttpContext.Response.StatusCode == 404)
ctx.HttpContext.Response.Redirect("/Path/To/Your/Action");
return Task.CompletedTask;
});
只需将其添加到UseMvc
上方。
答案 1 :(得分:0)
编辑:
对不起,我的第一个答案不正确。
IRouteCollection router = RouteData.Routers.OfType<IRouteCollection>().First();
以此,您可以将网址与控制器操作匹配
创建HttpContext进行测试(带有注入示例)
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