c# - 啊!为什么 System.Web.Mvc.HandleErrorInfo 会传递到我的 View ?

标签 c# asp.net-mvc controller views viewdata

我遇到了一个相当令人沮丧的问题。我的 MVC 网站大部分运行良好,但随机抛出错误(向用户显示友好错误)。当我检查日志时,这是我得到的:

System.InvalidOperationException: The model item passed into the dictionary is of type 'System.Web.Mvc.HandleErrorInfo' but this dictionary requires a model item of type 'BaseViewData'.

片刻之后,同一用户可以点击刷新并且页面加载正常。我卡住了。 ;(

更新:添加堆栈跟踪

System.Web.HttpUnhandledException: Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.InvalidOperationException: The model item passed into the dictionary is of type 'System.Web.Mvc.HandleErrorInfo' but this dictionary requires a model item of type 'BaseViewData'.
   at System.Web.Mvc.ViewDataDictionary`1.SetModel(Object value)
   at System.Web.Mvc.ViewDataDictionary..ctor(ViewDataDictionary dictionary)
   at System.Web.Mvc.HtmlHelper`1..ctor(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection)
   at System.Web.Mvc.ViewMasterPage`1.get_Html()
   at ASP.views_shared_site_master.__Render__control1(HtmlTextWriter __w, Control parameterContainer)
   at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
   at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
   at System.Web.UI.Control.Render(HtmlTextWriter writer)
   at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer)
   at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
   at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
   at System.Web.UI.Page.Render(HtmlTextWriter writer)
   at System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer)
   at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   --- End of inner exception stack trace ---
   at System.Web.UI.Page.HandleError(Exception e)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest()
   at System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context)
   at System.Web.UI.Page.ProcessRequest(HttpContext context)
   at ASP.views_shared_error_aspx.ProcessRequest(HttpContext context)
   at System.Web.Mvc.ViewPage.RenderView(ViewContext viewContext)
   at System.Web.Mvc.WebFormView.RenderViewPage(ViewContext context, ViewPage page)
   at System.Web.Mvc.WebFormView.Render(ViewContext viewContext, TextWriter writer)
   at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
   at System.Web.Mvc.Controller.ExecuteCore()
   at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
   at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext)
   at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext)
   at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext)
   at System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

最佳答案

Here是关于 codeplex 的问题解释为什么会出现该错误。

引自 http://web.archive.org/web/20131004122626/http://aspnet.codeplex.com/workitem/1795由于原始链接已失效:

HandleError Attribute should not store exception information in ViewData

When the HandleError attribute handles an exception, it stores the exception information in the ViewData. This is a problem when the Error.aspx inherits from the site.master and the site.master class is declared as follows.

public partial class Site : System.Web.Mvc.ViewMasterPage<SiteViewData>
{
}

SiteViewData contains:

public class SiteViewData 
{
  public String Title { get; set; } 
}

Each page ViewData class inherits from the SiteViewData class and looks something like this

public class IndexViewData : SiteViewData
{
  public String Message { get; set; }
  public String SupportedLanguages {get; set;}
}

This approach allows one to write code in the Site.Master page as follows

<title><%= Html.Encode(ViewData.Model.Title) %></title>

Unfortunately, when an exception is thrown, the model has been replaced with an instance of the HandleErrorInfo class. This causes an InvalidOperationException to be thrown with the information

The model item passed into the dictionary is of type System.Web.Mvc.HandleErrorInfo but this dictionary requires a model item of type Igwt.Boh.Website.Web.Controllers.SiteViewData.

Is it possible for a new ErrorData property to be added to the ViewResult class to store the instance of the HandleErrorInfo class instead? This way the ViewData does not get changed.

Chances are pretty good that any exception thrown in the action will occur after the IndexViewData (and SiteViewData) properties have already been initialized.

Closed Jan 27, 2010 at 12:24 AM by

Won't fix - see comments.


提到“wontfix”的评论来自 Microsoft 团队的一名前成员,以及他们解决该问题的建议(粗体):

By the time the [HandleError] attribute executes, we've lost the reference to the original ActionResult object. We don't even know if you intended to show a view anyway - maybe you intended to redirect. The part of the pipeline (the ViewResult) that would have been responsible for passing the model from the controller to the view is gone.

If an exception occurs, any model the application was working on should probably be treated as corrupt or unavailable anyway. The best practice would be to write your Error view such that neither it nor its dependencies (such as its master page) requires the original model.

关于c# - 啊!为什么 System.Web.Mvc.HandleErrorInfo 会传递到我的 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1997396/

相关文章:

javascript - 动态启用按钮

asp.net-mvc - 使用 ServiceStack MVC Powerpack + Funq 进行构造函数注入(inject)

asp.net-mvc - ASP.NET MVC 3 中 Dictionary<string, string> 的隐藏输入

c# - 检查属性在 FluentValidation 列表中是否唯一

c# - Process.Start 找不到现有文件

css - 网络服务器显示错误的布局

ruby-on-rails - 在 RSpec 测试中模拟子 uri

magento - 为 noRoute 操作覆盖 magento cms Controller

c# - 缺少命名空间或程序集引用时出错

c# - 从 Controller 内部的 Action 重定向?