如何使用 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 的新上下文。
有没有什么方法可以让操作过滤器创建的数据可供自定义错误视图使用?
I have an action filter that is responsible for placing some common information into the ViewBag for use by all views in the shared _Layout.cshtml file.
public class ProductInfoFilterAttribute : ActionFilterAttribute
{
public override void
OnActionExecuting(ActionExecutingContext filterContext)
{
// build product info
// ... (code omitted)
dynamic viewBag = filterContext.Controller.ViewBag;
viewBag.ProductInfo = info;
}
}
In the shared _Layout.cshtml file, I use the information that has been put into the ViewBag.
...
@ViewBag.ProductInfo.Name
...
If an exception occurs while processing a controller action, the standard HandleErrorAttribute should display my shared Error.cshtml view, and this worked before I introduced the action filter above and started using the new values from ViewBag in _Layout.cshtml. Now what I get is the standard ASP.Net runtime error page instead of my custom Error.cshtml view.
I have tracked this down to the fact that while rendering the error view, a RuntimeBinderException ("Cannot perform runtime binding on a null reference") is thrown on the use of ViewBag.ProductInfo.Name in _Layout.cshtml.
It appears that even though my action filter has successfully set the value in the ViewBag before the original exception was thrown, a new context with an empty ViewBag is used when rendering my Error.cshtml view.
Is there any way to get data created by an action filter to be available to a custom error view?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我通过添加另一个过滤器提出了自己的解决方案。
此过滤器需要通过调用
PreserveViewDataOnExceptionFilter.Register()
在 Global.asax.csApplication_Start()
方法中进行全局挂钩。我在这里所做的是设置一个新的异常过滤器,该过滤器在 HandleErrorAttribute 过滤器运行后最后运行,并复制 ViewData 集合的内容,该内容可供控制器使用,该控制器将异常抛出到由 HandleErrorAttribute 过滤器创建的结果中。
I have come up with my own solution through the addition of another filter.
This filter needs to be hooked in globally in the Global.asax.cs
Application_Start()
method by callingPreserveViewDataOnExceptionFilter.Register()
.What I've done here is to set up a new exception filter that runs last, after the HandleErrorAttribute filter runs, and copies the contents of the ViewData collection that was available to the controller that threw the exception into the result created by the HandleErrorAttribute filter.