5

我设计了一个使用or之ErrorController类的方法调用的控制器,因此我可以在 Web.config 中添加以下几行:ForbiddenNotFound

<customErrors mode="On" defaultRedirect="~/Error/Unknown" />
    <error statusCode="404" redirect="~/Error/NotFound" />
    <error statusCode="403" redirect="~/Error/Forbidden" />
</customErrors>

所以现在我希望能够做这样的事情:

public ActionResult Edit(int idObject)
{
    if( user.OnwsObject(idObject) )
    {
        // lets edit
    }
    else
    {
        // ** SEND AN ERROR 403 ***
        // And let ASP.NET MVC with IIS manage that error to send
        // the requester to the Web.config defined error page.
    }
}

问题是我尝试过类似的事情:(A)throw new HttpException(403, "Error description");:导致未处理的异常导致系统崩溃,(B)return HttpStatusResultCode(403, "Error description"):导致这些错误的系统默认页面。

我应该改用什么?

提前致谢。

4

2 回答 2

5

实际上,您不能将 web.config 用于 403 重定向。

您可以做的是覆盖OnActionExecuted控制器以检查状态代码并重定向到 web.config 中定义的任何内容,如下所示

网络配置:

<customErrors mode="On">
  <error statusCode="403" redirect="~/Error/Forbidden" />
</customErrors>

你的家庭控制器

public class HomeController : Controller
{
    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.HttpContext.Response.StatusCode == 403)
        {
            var config = (CustomErrorsSection)
                           WebConfigurationManager.GetSection("system.web/customErrors");
            string urlToRedirectTo = config.Errors["403"].Redirect;
            filterContext.Result = Redirect(urlToRedirectTo);
        }
        base.OnActionExecuted(filterContext);
    }

    public ActionResult Edit(int idObject)
    {
         if(!user.OnwsObject(idObject))
         {
             Response.StatusCode = 403;
         }

         return View();
    }
}

错误控制器:

public class ErrorController : Controller
{
    public ActionResult Forbidden()
    {
        Response.StatusCode = 403;
        return View();
    }
}

更通用的解决方案是创建一个可以应用于控制器或单个操作的操作过滤器:

public class HandleForbiddenRedirect : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.HttpContext.Response.StatusCode == 403)
        {
            var config = (CustomErrorsSection)
                           WebConfigurationManager.GetSection("system.web/customErrors");
            string urlToRedirectTo = config.Errors["403"].Redirect;
            filterContext.Result = new RedirectResult(urlToRedirectTo);
        }
        base.OnActionExecuted(filterContext);
    }
}

现在您可以将操作过滤器应用于控制器,以便所有操作都重定向到 403

[HandleForbiddenRedirect]
public class HomeController : Controller
{
    //...
}

或者在 403 上进行单独的操作重定向

public class HomeController : Controller
{
    [HandleForbiddenRedirect]
    public ActionResult Edit(int idObject)
    {
         //...
    }
}

或者,如果您不想装饰所有控制器和动作,但想在任何地方应用它,您可以将它添加到 Global.asax 的 Application_Start 的过滤器集合中

GlobalFilters.Filters.Add(new HandleForbiddenRedirect());
于 2013-07-26T11:11:24.027 回答
0

看到这篇文章这应该可以解决你的问题。

如何使自定义错误页面在 ASP.NET MVC 4 中工作

基本上你需要用 viewresult 或创建控制器

ASP.NET MVC 处理错误

于 2013-07-26T08:53:44.803 回答