Asp.net-Mvc
如何將 ViewData 傳遞給 HandleError 視圖?
在我的 Site.Master 文件中,我有 3 個簡單的 ViewData 參數(整個解決方案中只有 3 個)。這些 ViewData 值對於我的應用程序中的每個頁面都至關重要。由於在我的 Site.Master 中使用了這些值,因此我創建了一個抽象 SiteController 類,該類重寫 OnActionExecuting 方法,以便為解決方案中每個控制器上的每個 Action 方法填充這些值。
[HandleError(ExceptionType=typeof(MyException), View="MyErrorView")] public abstract class SiteController : Controller { protected override void OnActionExecuting(...) { ViewData["Theme"] = "BlueTheme"; ViewData["SiteName"] = "Company XYZ Web Portal"; ViewData["HeaderMessage"] = "Some message..."; base.OnActionExecuting(filterContext); } }我面臨的問題是,當 HandleErrorAttribute 從 SiteController 類級別屬性啟動時,這些值沒有傳遞給 MyErrorView(最終是 Site.Master)。這是一個簡單的場景來顯示我的問題:
public class TestingController : SiteController { public ActionResult DoSomething() { throw new MyException("pwnd!"); } }我也嘗試通過覆蓋 SiteController 中的 OnException() 方法來填充 ViewData 參數,但無濟於事。:(
在這種情況下,將 ViewData 參數傳遞給我的 Site.Master 的最佳方法是什麼?
這是因為當發生錯誤時,HandleErrorAttribute 會更改傳遞給視圖的 ViewData。它傳遞一個 HandleErrorInfo 類的實例,其中包含有關異常、控制器和操作的資訊。
您可以做的是將此屬性替換為以下實現的屬性:
using System; using System.Web; using System.Web.Mvc; public class MyHandleErrorAttribute : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { if (filterContext == null) { throw new ArgumentNullException("filterContext"); } if (!filterContext.ExceptionHandled && filterContext.HttpContext.IsCustomErrorEnabled) { Exception innerException = filterContext.Exception; if ((new HttpException(null, innerException).GetHttpCode() == 500) && this.ExceptionType.IsInstanceOfType(innerException)) { string controllerName = (string) filterContext.RouteData.Values["controller"]; string actionName = (string) filterContext.RouteData.Values["action"]; // Preserve old ViewData here var viewData = new ViewDataDictionary<HandleErrorInfo>(filterContext.Controller.ViewData); // Set the Exception information model here viewData.Model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName); filterContext.Result = new ViewResult { ViewName = this.View, MasterName = this.Master, ViewData = viewData, TempData = filterContext.Controller.TempData }; filterContext.ExceptionHandled = true; filterContext.HttpContext.Response.Clear(); filterContext.HttpContext.Response.StatusCode = 500; filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; } } } }