Автоматическая обработка ошибок C# MVC
У меня есть этот код.
public ActionResult Index()
{
ReceiptModel model = new ReceiptModel();
try
{
model = new ReceiptModel(context);
}
catch (BussinessException bex)
{
ModelState.AddModelError("Index", bex.MessageToDisplay);
return View("Index");
}
return View(model);
}
BussinesException возвращается из базы данных и затем отображается для пользователя. Я должен поставить на каждый оператор try-catch метод контроллера, что немного утомительно. Есть ли более простой способ, как обработать эти исключения?
PS Все остальные исключения обрабатываются с HandleExceptionAttribute
ОБНОВИТЬ:
Я использовал подход Floradu88. Так что теперь у меня есть что-то вроде этого.
public sealed class HandleBussinessExceptionAttribute : HandleErrorAttribute, IExceptionFilter
{
public override void OnException(ExceptionContext filterContext)
{
filterContext.Controller.TempData["UnhandledException"] = filterContext.Exception;
filterContext.ExceptionHandled = true;
((Controller)filterContext.Controller).ModelState.AddModelError(
((BussinessException)filterContext.Exception).Code.ToString(),
((BussinessException)filterContext.Exception).MessageToDisplay
);
filterContext.Result = new ViewResult
{
ViewName = this.View,
TempData = filterContext.Controller.TempData,
ViewData = filterContext.Controller.ViewData,
};
}
}
и на действие контроллера я положил
[HandleBussinessExceptionAttribute(Order = 2, ExceptionType = typeof(BussinessException), View = "Login")]
я также попробовал в обработчике исключений:
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(filterContext.RouteData));
а затем обработать ошибку в действии с ModelState.IsValid
но значения к действию не имеют значения. Так что сейчас я использую первый подход. Когда у меня будет немного больше времени, я постараюсь исправить второй подход.
2 ответа
Пожалуйста, прочтите документацию по этой части: http://msdn.microsoft.com/en-us/library/gg416513%28v=vs.98%29.aspx
http://www.asp.net/web-api/overview/web-api-routing-and-actions/exception-handling
http://www.asp.net/mvc/tutorials/older-versions/controllers-and-routing/understanding-action-filters-cs
Слишком много контента для размещения здесь:
public class NotImplExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
if (context.Exception is NotImplementedException)
{
context.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented);
}
}
}
И ваш контроллер:
public class ProductsController : ApiController
{
[NotImplExceptionFilter]
public Contact GetContact(int id)
{
throw new NotImplementedException("This method is not implemented");
}
}
Согласно этому посту, создайте пользовательское связующее и поместите модель в TempData:
public class AppBinder : DefaultModelBinder { protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) { base.OnModelUpdated(controllerContext, bindingContext); controllerContext.Controller.TempData["model"] = bindingContext.Model; } }
Зарегистрируйте это в global.asax:
ModelBinders.Binders.DefaultBinder = new AppBinder();
Создайте BaseController и переопределите OnException:
protected override void OnException(ExceptionContext filterContext) { filterContext.ExceptionHandled = true; this.ModelState.AddModelError(string.Empty, filterContext.Exception.Message); filterContext.Result = new ViewResult { ViewName = filterContext.RouteData.Values["action"].ToString(), TempData = filterContext.Controller.TempData, ViewData = filterContext.Controller.ViewData }; base.OnException(filterContext); }
Все действия int Контроллеры, унаследованные от этого базового контроллера, покажут свои необработанные исключения в собственном представлении проверки (не забудьте иметь
@Html.ValidationSummary(true)
на странице). это работает для меня, надежда работает для вас тоже!