2013-07-26 4 views
3

Я разработал контроллер под названием ErrorController с методами, как Forbidden или NotFound, так что я мог бы добавить в Web.config следующие строки:Возвращающиеся пользовательские ошибки

<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"): в результате в системе defau lt страницы для этих ошибок.

Что следует использовать вместо этого?

Заранее спасибо.

+0

сделал вы пытаетесь добавить Response.StatusCode = 403 ; ? а затем вернуть Json в результате описания ошибки? – taffarel

+0

Показывает страницу по умолчанию IIS, а не пользовательскую :( –

ответ

4

На самом деле вы не можете использовать web.config для 403 редиректа.

Что вы можете сделать, это переопределить OnActionExecuted на контроллере для проверки кода статуса и перенаправлять все, что определено в файле web.config, как этот

Web.config:

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

Ваш HomeController

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(); 
    } 
} 

ErrorController:

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) 
    { 
     //... 
    } 
} 

Или, если вы не обыкновение украшать все контроллеры и действия, но хотите, чтобы применить его везде, где вы можете добавить его в коллекцию фильтров в Application_Start из Global.asax

GlobalFilters.Filters.Add(new HandleForbiddenRedirect()); 
+0

Позвольте мне проверить ее сегодня вечером, отлично выглядит –