Cha*_*eus 28 c# asp.net-mvc viewdata controller views
我遇到了一个相当令人沮丧的问题.我的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'.
Run Code Online (Sandbox Code Playgroud)
片刻之后,同一个用户可以点击刷新并且页面加载正常.我被卡住了.(
更新:添加堆栈跟踪
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)
Run Code Online (Sandbox Code Playgroud)
Çağ*_*kin 17
引自http://web.archive.org/web/20131004122626/http://aspnet.codeplex.com/workitem/1795,因为原始链接已死:
HandleError属性不应在ViewData中存储异常信息
当
HandleError属性处理异常时,它将异常信息存储在ViewData.当Error.aspx从site.master和site.master类的继承声明如下时,这是一个问题.Run Code Online (Sandbox Code Playgroud)public partial class Site : System.Web.Mvc.ViewMasterPage<SiteViewData> { }
SiteViewData包含:Run Code Online (Sandbox Code Playgroud)public class SiteViewData { public String Title { get; set; } }每个页面
ViewData类都继承自SiteViewData类,看起来像这样Run Code Online (Sandbox Code Playgroud)public class IndexViewData : SiteViewData { public String Message { get; set; } public String SupportedLanguages {get; set;} }这种方法允许用户在
Site.Master页面中编写代码如下Run Code Online (Sandbox Code Playgroud)<title><%= Html.Encode(ViewData.Model.Title) %></title>不幸的是,当抛出异常时,模型已被替换为
HandleErrorInfo类的实例.这会导致InvalidOperationException信息被抛出传递到字典中的模型项是类型的,
System.Web.Mvc.HandleErrorInfo但此字典需要类型的模型项Igwt.Boh.Website.Web.Controllers.SiteViewData.是否可以将新
ErrorData属性添加到ViewResult类中以存储类的实例HandleErrorInfo?这样ViewData就不会改变.在
IndexViewData(和SiteViewData)属性已经初始化之后,动作中抛出的任何异常都很有可能.关闭2010年1月27日上午12:24 by
无法修复 - 请参阅评论.
"wontfix"中提到的评论来自微软团队的前成员,以及他们为解决它而提出的建议(加粗):
到[HandleError]属性执行时,我们已经丢失了对原始ActionResult对象的引用.我们甚至不知道您是否打算显示视图 - 也许您打算重定向.管道的一部分(ViewResult)负责将模型从控制器传递到视图.
如果发生异常,应用程序正在处理的任何模型都应该被视为已损坏或无法使用.最佳做法是编写错误视图,使其及其依赖关系(例如其母版页)都不需要原始模型.
我解决这个问题的方法是删除布局页面顶部的@model指令然后做一些检查,我通常希望看到我的模型在可能传入的不同模型之间切换,例如
@if (Model is System.Web.Mvc.HandleErrorInfo)
{
<title>Error</title>
}
else if (Model.GetType() == typeof(MyApp.Models.BaseViewModel))
{
<meta name="description" content="@Model.PageMetaDescription">
<title>@Model.PageTitleComplete</title>
}
Run Code Online (Sandbox Code Playgroud)