【问题标题】:How do I ensure my MVC app redirects to an error page when a certain exception occurs?当某个异常发生时,如何确保我的 MVC 应用程序重定向到错误页面?
【发布时间】:2011-08-17 16:04:04
【问题描述】:

我见过一个很好的例子,其中 MVC 控制器类继承自另一个控制器类,该控制器类处理异常并返回内部错误的视图,如下所示:

public class ApplicationController : Controller
{
    public ActionResult NotFound()
    {
        return View("NotFound");
    }

    public ActionResult InsufficientPriveleges()
    {
        return View("InsufficientPriveleges");
    }

    protected override void OnException(ExceptionContext filterContext)
    {
        if (filterContext.Exception is NotFoundException)
        {
            filterContext.Result = NotFound();
            filterContext.ExceptionHandled = true;
            return;
        }
        if (filterContext.Exception is InsufficientPrivelegesException)
        {
            filterContext.Result = InsufficientPriveleges();
            filterContext.ExceptionHandled = true;
            return;
        }

        base.OnException(filterContext);
    }
}

但是,我注意到,例如,我的控制器正在为用户不应访问的内容加载部分视图,然后该错误将显示在页面的部分视图中。

我希望整个页面都显示错误,实际上异常应该重定向到一个全新的页面。如何使用上面显示的当前类来实现这一点?

【问题讨论】:

  • 我想这会回答你的问题:stackoverflow.com/questions/550995/…
  • 我似乎无法在子操作中引发异常。我认为我需要能够在服务层的任何地方抛出异常,无论我在渲染管道中的哪个位置,并让重定向发生。有什么想法吗?
  • 您介意展示有问题的局部视图和相关操作吗?也许在部分视图的情况下处理得当......
  • 是的,在 Razor 视图中,我使用 Html.RenderAction()。这会调用控制器上的子操作来呈现局部视图。在渲染视图时,调用服务来获取一些数据。此时,如果不允许用户查看数据,服务可能会抛出异常。我不认为 MVC 喜欢在渲染管道内抛出异常。不知道如何解决这个问题...

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


【解决方案1】:

您可以在 web.config 中创建从 HTTP 结果代码到特定错误处理程序的映射:

<customErrors mode="On" defaultRedirect="~/Error">
  <error statusCode="401" redirect="~/Error/Unauthorized" />
  <error statusCode="404" redirect="~/Error/NotFound" />
</customErrors>

然后创建一个自定义错误控制器

public class ErrorController
{ 
        public ActionResult Index ()
        {
            return View ("Error");
        }

        public ActionResult Unauthorized ()
        {
            return View ("Error401");
        }

        public ActionResult NotFound ()
        {
            return View ("Error404");
    }
    }

然后从你的控制器中抛出一个 HttpException

public ActionResult Test ()
{
    throw new HttpException ((int)HttpStatusCode.Unauthorized, "Unauthorized");
}

另一种选择是使用自定义FilterAttribute 来检查引发 HttpException 的权限

[Authorize (Roles = SiteRoles.Admin)]
public ActionResult Test ()
{
  return View ();
}

【讨论】:

  • 查看我上面关于在子操作中抛出异常的评论。
  • 更新:上述方法有效,但我可能会补充说,如果您想有效地呈现新的错误页面,则尝试在控制器上的子操作中引发异常会导致问题。相反,我从控制器上的主要操作而不是任何子操作检查并引发异常。
【解决方案2】:

您必须以不同的方式处理 ajax 调用。我会简单地使用 jquery $.ajax 的 error() 来处理这种 ajax 调用错误。

$.ajax({
    ...
    success: function(g) {
          //process normal
    },
    error: function(request, status, error) {
          //process exception here
    }
})

【讨论】:

    猜你喜欢
    • 2015-01-04
    • 2011-08-07
    • 2017-07-08
    • 2013-04-11
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多