在不更改url的情况下显示自定义页面

时间:2019-07-01 09:06:39

标签: c# url redirect asp.net-core-mvc

当用户尝试访问不应访问的内容时,我想显示一个页面。此限制是在自定义中间件中检查的。当中间件返回false并调用新控制器时,我不希望更改客户端url。

这是我的中间件检查:

public async Task Invoke(HttpContext context, IAutorisationService service)
        {
            var user = service.CreateUserModel(context);
            var page = service.CreatePageModel(context);
            context.Items.Add("CurrentUser", user);

            if (service.UserAllowedToPage(user, page))
                await _next.Invoke(context);
            else
            {
                context.Response.Redirect("/Error/CustomError");
            }
        }

这是错误控制器:

public IActionResult CustomError()
        {
            if (!HttpContext.Items.TryGetValue("CurrentUser", out var o) || !(o is UserModel userModel))
            {
                return View();
            }

            if (userModel.IsSuperUser)
            {
                return View();
            }

这里返回的视图都可以正常工作。

这是我的startup.cs(我现在在这里苦苦挣扎):

app.UseMvc(routes =>
            {
                //routes.MapRoute(
                    //name: "ErrorRoute",
                    //template: "{controller=Error}",
                    //defaults: new {controller = "Error", action = "CustomError"});

                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");

            });

我在网上找到的任何组合似乎都无法正确实现。

更新

好的,所以我对政策没有进一步的了解。 我会尽力解释一下我的情况: 我在管道的末尾有一个自定义的中间件(就在app.UseMvc之前) 该中间件具有异步Task Invoke方法,该方法在另一个类中调用布尔运算符。 现在,如果布尔值返回true,则中间件任务将执行:await _next.Invoke(HttpContext),并且如果该布尔值返回false,我希望中间件执行异常。 当引发异常时,我需要:app.UseExceptionHandler("/Error/CustomError");app.UseStatusCodePagesWithReExecute("/Error/CustomError"); 捕获它并在ErrorController中激活CustomError操作,然后返回一个自定义视图。这有可能吗? (很抱歉,我的第一个问题还没有完成)

2 个答案:

答案 0 :(得分:0)

您可以使用

返回错误视图
return View("Error")

您可以检查所需的内容,如果出现问题,可以从主视图返回错误视图

答案 1 :(得分:0)

您不能重定向到页面,而无需更改URL。重定向实际上发生在客户端。服务器仅发送带有包含备用URL的Location头的302响应。客户有责任实际请求该备用URL,这是浏览器默认执行的操作。结果,浏览器实际上将请求/Error/CustomError

您需要做的是直接从中间件返回实际的错误响应,以使URL保持原样。但是,实际上,中间件在这里是错误的方法。

相反,您应该使用内置的授权框架。您可以通过实现需求和处理程序,然后使用Authorize属性引用该策略,将自定义策略应用于控制器/操作:

[Authorize(Policy = "MyPolicy")]
public IActionResult MyProtectedAction()

然后,当用户不满足策略要求时,他们将陷入异常处理中间件中,您可以在其中通过配置app.UseStatusCodePagesWithReExecute来绑定自定义视图:

public class Startup
{
    ...

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseStatusCodePagesWithReExecute("/error/{0}");

        ...
    }
}

这将执行为/error/{0}路由定义的控制器和操作,而不会影响URL(“ ReExecute”部分)。 {0}位将被HTTP状态代码替换为401 Unauthorized。因此,您实际上可以将操作绑定到/error/401或使用/error/{statusCode}之类的路由来捕获所有操作,然后在状态代码内分支以处理多种不同的错误类型。无论价格多少,这也是您提供自定义404页,500页等的方式。

有关更多信息,请参见: