2012-01-11 4 views
3

У меня есть исключения и перенаправление пользователей на страницу с ошибкой. Я передаю сообщение об исключении и URL-адрес возврата, чтобы сообщить пользователю, что произошло, и позволить им вернуть другую страницу.ASP.NET MVC - декларативная переадресация при ошибке

 try 
     { 
      return action(parameters); 
     } 
     catch (Exception exception) 
     { 
      ErrorViewModel errorModel = new ErrorViewModel(); 
      errorModel.ErrorMessage = "An error occured while doing something."; 
      errorModel.ErrorDetails = exception.Message; 
      errorModel.ReturnUrl = Url.Action("Controller", "Action"); 
      return RedirectToAction("Index", "Error", errorModel); 
     } 

Это похоже образом слишком много кода, чтобы обернуть вокруг каждого действия. Я использую глобальный фильтр для ошибок:

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     HandleErrorAttribute attribute = new HandleErrorAttribute(); 
     filters.Add(attribute); 
    } 

и у меня есть мои настройки web.config как это:

<customErrors mode="On" defaultRedirect="~/Error/Unknown"> 

Но это работает только для необработанных исключений.

Я хочу, чтобы исключения вызывали перенаправление на контроллер ошибок/действие с параметром, содержащим данные об исключении. Было бы неплохо, если бы я мог указывать обратный URL-адрес по принципу действия за действиями или иметь значение по умолчанию, если оно не указано.

ответ

3

Вот немного RedirectOnErrorAttribute класс я создал:

using System; 
using System.Web.Mvc; 
using MyApp.Web.Models; 

namespace MyApp.Web.Utilities 
{ 
    public class RedirectOnErrorAttribute : ActionFilterAttribute 
    { 
     /// <summary> 
     /// Initializes a new instance of a RedirectOnErrorAttribute. 
     /// </summary> 
     public RedirectOnErrorAttribute() 
     { 
      ErrorMessage = "An error occurred while processing your request."; 
     } 

     /// <summary> 
     /// Gets or sets the controller to redirect to. 
     /// </summary> 
     public string ReturnController { get; set; } 

     /// <summary> 
     /// Gets or sets the action to redirect to. 
     /// </summary> 
     public string ReturnAction { get; set; } 

     /// <summary> 
     /// Gets or sets the error message. 
     /// </summary> 
     public string ErrorMessage { get; set; } 

     /// <summary> 
     /// Redirects the user to an error screen if an exception is thrown. 
     /// </summary> 
     /// <param name="filterContext">The filter context.</param> 
     public override void OnActionExecuted(ActionExecutedContext filterContext) 
     { 
      if (filterContext.Exception != null && !filterContext.ExceptionHandled) 
      { 
       ErrorViewModel viewModel = new ErrorViewModel(); 
       viewModel.ErrorMessage = ErrorMessage; 
       viewModel.ErrorDetails = filterContext.Exception.Message; 
       string controller = ReturnController; 
       string action = ReturnAction; 
       if (String.IsNullOrWhiteSpace(controller)) 
       { 
        controller = (string)filterContext.RequestContext.RouteData.Values["controller"]; 
       } 
       if (String.IsNullOrWhiteSpace(action)) 
       { 
        action = "Index"; 
       } 
       UrlHelper helper = new UrlHelper(filterContext.RequestContext); 
       viewModel.ReturnUrl = helper.Action(action, controller); 
       string url = helper.Action("Index", "Error", viewModel); 
       filterContext.Result = new RedirectResult(url); 
       filterContext.ExceptionHandled = true; 
      } 
      base.OnActionExecuted(filterContext); 
     } 
    } 
} 

Теперь я могу украсить все мои действия, как это:

[RedirectOnError(ErrorMessage="An error occurred while doing something.", ReturnController="Controller", ReturnAction="Action")] 
+0

Это помогло ... Так чертовски много – TheGeekZn

3

Вместо того чтобы помещать попытку catch в каждое действие, вы можете переопределить событие OnException контроллера. Это событие содержит все детали исключения. Все остальные настройки выглядят правильно.

[HandleError] 
    public class AccountController : Controller 
    { 
     [HttpPost] 
     public ActionResult YourAction(SomeModel model) 
     { 
      //do stuff but don't catch exception 
      return View(); 
     } 
     protected override void OnException(ExceptionContext filterContext) 
     { 
      EventLog.WriteEntry("YourProjectEventName", filterContext.Exception.ToString(), EventLogEntryType.Error); 
      base.OnException(filterContext); 
     } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^