1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Web;
5: using System.Web.Mvc;
6: using Artech.Mvc.ExceptionHandling.Configuration;
7: using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
8: using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
9: namespace Artech.Mvc.ExceptionHandling
10: {
11: public class ExceptionActionInvoker: ControllerActionInvoker
12: {
13: protected ExceptionHandlingSettings ExceptionHandlingSettings{get; private set;}
14: protected virtual Func<string, HandleErrorInfo, ViewResult> GetErrorView { get; private set; }
15: public ExceptionPolicyImpl ExceptionPolicy { get; private set; }
16: public ExceptionActionInvoker(string exceptionPolicy,Func<string, HandleErrorInfo, ViewResult> getErrorView)
17: {
18: this.ExceptionPolicy = EnterpriseLibraryContainer.Current.GetInstance<ExceptionPolicyImpl>(exceptionPolicy);
19: this.GetErrorView = getErrorView;
20: this.ExceptionHandlingSettings = ExceptionHandlingSettings.GetSection();
21: }
22:
23: public override bool InvokeAction(ControllerContext controllerContext, string handleErrorActionName)
24: {
25: ExceptionContext exceptionContext = controllerContext as ExceptionContext;
26: if (null == exceptionContext)
27: {
28: throw new ArgumentException("The controllerContext must be ExceptionContext!", "controllerContext");
29: }
30: try
31: {
32: exceptionContext.ExceptionHandled = true;
33: if (this.ExceptionPolicy.HandleException(exceptionContext.Exception))
34: {
35: HandleRethrownException(exceptionContext);
36: }
37: else
38: {
39: if (ExceptionHandlingContext.Current.Errors.Count == 0)
40: {
41: ExceptionHandlingContext.Current.Errors.Add(exceptionContext.Exception.Message);
42: }
43: ControllerDescriptor controllerDescriptor = this.GetControllerDescriptor(exceptionContext);
44: ActionDescriptor handleErrorAction = FindAction(exceptionContext, controllerDescriptor, handleErrorActionName);
45: if (null != handleErrorAction)
46: {
47: IDictionary<string, object> parameters = GetParameterValues(controllerContext, handleErrorAction);
48: exceptionContext.Result = this.InvokeActionMethod(exceptionContext, handleErrorAction, parameters);
49: }
50: else
51: {
52: HandleRethrownException(exceptionContext);
53: }
54: }
55: return true;
56: }
57: catch (Exception ex)
58: {
59: exceptionContext.Exception = ex;
60: HandleRethrownException(exceptionContext);
61: return true;
62: }
63: }
64: protected virtual void HandleRethrownException(ExceptionContext exceptionContext)
65: {
66: string errorViewName = this.GetErrorViewName(exceptionContext.Exception.GetType());
67: string controllerName = (string)exceptionContext.RouteData.GetRequiredString("controller");
68: string action = (string)exceptionContext.RouteData.GetRequiredString("action");
69: HandleErrorInfo handleErrorInfo = new HandleErrorInfo(exceptionContext.Exception, controllerName, action);
70: exceptionContext.Result = this.GetErrorView(errorViewName, handleErrorInfo);
71: }
72: protected string GetErrorViewName(Type exceptionType)
73: {
74: ExceptionErrorViewElement element = ExceptionHandlingSettings.ExceptionErrorViews
75: .Cast<ExceptionErrorViewElement>().FirstOrDefault(el=>el.ExceptionType == exceptionType);
76: if(null != element)
77: {
78: return element.ErrorView;
79: }
80: if(null== element && null != exceptionType.BaseType!= null)
81: {
82: return GetErrorViewName(exceptionType.BaseType);
83: }
84: else
85: {
86: return "Error";
87: }
88: }
89: }
90: }