Asp.net-Mvc
如何使用 Error.cshtml 視圖中的過濾器放入 ViewBag 的數據?
我有一個動作過濾器,負責將一些通用資訊放入 ViewBag 中,以供共享 _Layout.cshtml 文件中的所有視圖使用。
public class ProductInfoFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { // build product info // ... (code omitted) dynamic viewBag = filterContext.Controller.ViewBag; viewBag.ProductInfo = info; } }在共享的_Layout.cshtml 文件中,我使用了已放入ViewBag 的資訊。
... @ViewBag.ProductInfo.Name ...如果在處理控制器操作時發生異常,標準的 HandleErrorAttribute 應該顯示我共享的 Error.cshtml 視圖,這在我引入上面的操作過濾器並開始使用 _Layout.cshtml 中的 ViewBag 的新值之前有效。現在我得到的是標準的 ASP.Net 執行時錯誤頁面,而不是我的自定義 Error.cshtml 視圖。
我已將此歸結為以下事實:在呈現錯誤視圖時,在 _Layout.cshtml 中使用 ViewBag.ProductInfo.Name 時會引發 RuntimeBinderException(“無法對空引用執行執行時綁定”)。
看起來即使我的操作過濾器在引發原始異常之前已成功設置 ViewBag 中的值,但在呈現我的 Error.cshtml 視圖時仍使用具有空 ViewBag 的新上下文。
有什麼方法可以讓操作過濾器創建的數據可用於自定義錯誤視圖?
我通過添加另一個過濾器提出了自己的解決方案。
public class PreserveViewDataOnExceptionFilter : IExceptionFilter { public void OnException(ExceptionContext filterContext) { // copy view data contents from controller to result view ViewResult viewResult = filterContext.Result as ViewResult; if ( viewResult != null ) { foreach ( var value in filterContext.Controller.ViewData ) { if ( ! viewResult.ViewData.ContainsKey(value.Key) ) { viewResult.ViewData[value.Key] = value.Value; } } } } public static void Register() { FilterProviders.Providers.Add(new FilterProvider()); } private class FilterProvider : IFilterProvider { public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) { // attach filter as "first" for all controllers / actions; note: exception filters run in reverse order // so this really causes the filter to be the last filter to execute yield return new Filter(new PreserveViewDataOnExceptionFilter(), FilterScope.First, null); } } }此過濾器需要
Application_Start()通過呼叫全域掛接到 Global.asax.cs 方法中PreserveViewDataOnExceptionFilter.Register()。我在這裡所做的是設置一個新的異常過濾器,該過濾器在 HandleErrorAttribute 過濾器執行之後最後執行,並將 ViewData 集合的內容複製給將異常拋出到由 HandleErrorAttribute 過濾器創建的結果的控制器.