2009-11-25 16 views
13

Site.Master dosyasında, 3 basit ViewData parametresi (tüm çözümümde yalnızca 3) var. Bu ViewData değerleri, uygulamamdaki her bir sayfa için kritik öneme sahiptir. Bu değerler benim sitemde kullanıldığından, çözümümdeki her denetleyicideki her Eylem yöntemi için bu değerleri doldurmak üzere OnActionExecuting yöntemini geçersiz kılan soyut bir SiteController sınıfı oluşturdum.ViewData'yı HandleError View'a nasıl geçiririm?

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

    } 
} 

Ben ile karşı karşıya ediyorum sorun HandleErrorAttribute SiteController sınıf seviyesi özelliğinden de tekmelediğinde bu değerler (sonuçta ve Site.Master) MyErrorView geçirilmediğini olmamasıdır. İşte benim problem göstermek için basit bir senaryodur: Ben ama boşuna yanı benim SiteController içinde OnException() yöntemini geçersiz kılarak ViewData parametreleri doldurarak denedim

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

. :(

Ne bu durumda benim Site.Master için ViewData parametrelerini geçirmek için en iyi yoldur? HandleErrorAttribute ViewData bir hata oluşursa görünümüne geçirilen değiştirir Bunun nedeni

cevap

19

. Bu bir örneğini geçer . sadece ViewBag aracılığıyla bir şeyler geçmek gerekirse

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

Vay, bu çok bunun olacağını düşündüğümden daha karmaşık oldu. :) Anladım ve bunu anlamak için ne yaptığınızı ve neden yaptığınızı mükemmel bir şekilde anladım. Cevabınız için teşekkürler! – Luc

+1

bu aslında çalışmıyor ... – fearofawhackplanet

+0

"çalışmıyor" özellikle yararlı değildir. Ben ve diğerleri için yaptım. Kullandığınız MVC versiyonunu kontrol etmelisiniz, çok değiştiğinden eminim. –

3

o don olabilir: İstisna, Kontrolör ve Eylem hakkında bilgi HandleErrorInfo sınıf

ne yapabilirsiniz aşağıda uygulanan biriyle bu niteliği değiştirmek olduğunu Bu gibi e:

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

     base.OnException(filterContext); 
    } 

İşte bakın (bu benim denetleyicileri devralan bir BaseController içinde olur): How can I use data placed into a ViewBag by a filter in my Error.cshtml view?