2009-11-25 148 views
13

在我的Site.Master文件中,我有3個簡單的ViewData參數(我的整個解決方案中只有3個)。這些ViewData值對於我的應用程序中的每個頁面都很重要。由於在我的Site.Master中使用了這些值,我創建了一個抽象的SiteController類,它覆蓋了OnActionExecuting方法,爲我的解決方案中每個控制器上的每個Action方法填充這些值。如何將ViewData傳遞給HandleError視圖?

[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); 

    } 
} 

我正在面臨的問題是,這些值不被傳遞給MyErrorView(並且最終的Site.Master)當HandleErrorAttribute從SiteController類級別屬性在踢。下面是一個簡單的場景來展現我的問題:

public class TestingController : SiteController 
{ 
    public ActionResult DoSomething() 
    { 
    throw new MyException("pwnd!"); 
    } 
} 

我試圖通過覆蓋在我的SiteController的onException的()方法,以及填充ViewData的參數,但無濟於事。 :(

什麼是通過在這種情況下,ViewData的參數,我的Site.Master的最佳方式?

回答

19

這是因爲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; 
      } 
     } 
    } 
} 
+0

哇,這是一個很多比我想象的要複雜得多。 :)我已經通過它來了解它,它是完全有意義的,你在做什麼,爲什麼你這樣做。感謝您的回答! – Luc 2009-12-01 19:29:31

+1

這實際上並不工作... – fearofawhackplanet 2012-01-17 12:47:15

+0

「不起作用」並不特別有用。我爲我和其他人做了。你應該檢查你使用的MVC版本,因爲我相信很多改變了。 – 2012-01-17 19:47:14

3

如果你只需要通過ViewBag傳遞的東西也可以是唐è這樣的:(這恰好是在BaseController我所有的控制器繼承)

protected override void OnException(ExceptionContext filterContext) 
    { 
     try 
     { 
      var v = filterContext.Result as ViewResult; 
      v.ViewBag.DataToPassToError = "Hello World!"; 
     } 
     catch { /* no-op */ } 

     base.OnException(filterContext); 
    } 

在這裏看到:How can I use data placed into a ViewBag by a filter in my Error.cshtml view?

相關問題