如果未找到请求的操作,则重定向到指定的操作

问题描述 投票:0回答:2

如何将控制器中找不到的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?}"
        );

});

任何线索如何解决这个问题?问候

asp.net-mvc asp.net-core
2个回答
2
投票

只要有404,就可以使用UseStatusCodePages实现简单的重定向。这就是它的样子:

app.UseStatusCodePages(ctx =>
{
    if (ctx.HttpContext.Response.StatusCode == 404)
        ctx.HttpContext.Response.Redirect("/Path/To/Your/Action");

    return Task.CompletedTask;
});

只需将它添加到UseMvc上方。


0
投票

编辑:

对不起,我的第一个答案是不对的。

  1. IRouteCollection router = RouteData.Routers.OfType<IRouteCollection>().First();

有了这个,你可以匹配一个url到控制器动作

  1. 创建用于测试的HttpContext(带注入的示例) private readonly IHttpContextFactory _httpContextFactory; public HomeController( IHttpContextFactory httpContextFactory) { _httpContextFactory = httpContextFactory; }
  2. 使用值创建上下文 HttpContext context = _httpContextFactory.Create(HttpContext.Features); context.Request.Path = "/Home/Index"; context.Request.Method = "GET";
  3. 检查路线 var routeContext = new RouteContext(context); await router.RouteAsync(routeContext); bool exists = routeContext.Handler != null;

进一步阅读:https://joonasw.net/view/find-out-if-url-matches-action

© www.soinside.com 2019 - 2024. All rights reserved.