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

时间:2018-09-18 12:02:14

标签: asp.net-mvc asp.net-core

如何将控制器中未找到的动作重定向到同一控制器中的另一个动作?假设通过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?}"
        );

});

有什么线索可以解决这个问题吗? 问候

2 个答案:

答案 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)

编辑:

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

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

以此,您可以将网址与控制器操作匹配

  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