Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exceptions leaking and cause view to render without PageModel #36

Open
jhorsman opened this issue Dec 13, 2016 · 5 comments
Open

Exceptions leaking and cause view to render without PageModel #36

jhorsman opened this issue Dec 13, 2016 · 5 comments

Comments

@jhorsman
Copy link
Contributor

Sometimes DXA renders a page like this:
image

Error message

Server Error in '/' Application.
The model item passed into the dictionary is of type 'System.Web.Mvc.HandleErrorInfo', but this dictionary requires a model item of type 'Sdl.Web.Common.Models.PageModel'.

It looks like an exception is not caught by DXA, the webapp then wants to render an error message, the _Layout.cshtml is loaded and that one expects a PageModel object which of course is not present.

This happens for example when an entity view model is not registered.

@rpannekoek
Copy link
Contributor

When an exception occurs while rendering a Region or Entity View, DXA tries to render the error using the SectionError View (which is normally in your Web App in \Views\Shared\SectionError.cshtml). It passes a Model of type HandleErrorInfo (which is expected by that View).

@jhorsman
Copy link
Contributor Author

jhorsman commented Dec 13, 2016

I have a Views/Shared/SectionError.cshtml in my website project. Should it be registered somewhere? I see that it indeed expects the System.Web.Mvc.HandleErrorInfo model which is mentoned in the error message as well.

@jhorsman
Copy link
Contributor Author

Here is some more stacktrace

2016-12-13 15:42:57,429 [5] ERROR - No View Model registered for View 'MyModule:EComWidget:Categories'. Check that you have registered this View in the 'MyModule' area registration.
Sdl.Web.Common.DxaException: No View Model registered for View 'MyModule:EComWidget:Categories'. Check that you have registered this View in the 'MyModule' area registration.
   at Sdl.Web.Common.Models.ModelTypeRegistry.GetViewModelType(MvcData viewData)
   at Sdl.Web.Tridion.Mapping.DefaultModelBuilder.BuildEntityModel(EntityModel& entityModel, IComponentPresentation cp, Localization localization)
   at Sdl.Web.Tridion.Mapping.ModelBuilderPipeline.CreateEntityModel(IComponentPresentation cp, Localization localization)
   at Sdl.Web.Tridion.Mapping.DefaultModelBuilder.BuildPageModel(PageModel& pageModel, IPage page, IEnumerable`1 includes, Localization localization)
2016-12-13 15:43:00,298 [5] ERROR - The model item passed into the dictionary is of type 'Sdl.Web.Common.Models.ExceptionEntity', but this dictionary requires a model item of type 'Sdl.Web.Common.Models.PageModel'.
System.InvalidOperationException: The model item passed into the dictionary is of type 'Sdl.Web.Common.Models.ExceptionEntity', but this dictionary requires a model item of type 'Sdl.Web.Common.Models.PageModel'.
   at System.Web.Mvc.ViewDataDictionary`1.SetModel(Object value)
   at System.Web.Mvc.ViewDataDictionary..ctor(ViewDataDictionary dictionary)
   at System.Web.Mvc.WebViewPage`1.SetViewData(ViewDataDictionary viewData)
   at System.Web.Mvc.WebViewPage.ConfigurePage(WebPageBase parentPage)
   at System.Web.WebPages.WebPageBase.<>c__DisplayClass3.<RenderPageCore>b__2(TextWriter writer)
   at System.Web.WebPages.HelperResult.WriteTo(TextWriter writer)
   at System.Web.WebPages.WebPageBase.Write(HelperResult result)
   at System.Web.WebPages.WebPageBase.RenderSurrounding(String partialViewName, Action`1 body)
   at System.Web.WebPages.WebPageBase.PopContext()
   at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
   at RazorGenerator.Mvc.PrecompiledMvcView.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.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.<BeginInvokeAction>b__1c()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)
2016-12-13 15:43:00,414 [5] ERROR - Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'.
System.Web.HttpException (0x80004005): Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'. ---> 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 'Sdl.Web.Common.Models.PageModel'.
   at System.Web.Mvc.ViewDataDictionary`1.SetModel(Object value)
   at System.Web.Mvc.ViewDataDictionary..ctor(ViewDataDictionary dictionary)
   at System.Web.Mvc.WebViewPage`1.SetViewData(ViewDataDictionary viewData)
   at System.Web.Mvc.WebViewPage.ConfigurePage(WebPageBase parentPage)
   at System.Web.WebPages.WebPageBase.<>c__DisplayClass3.<RenderPageCore>b__2(TextWriter writer)
   at System.Web.WebPages.HelperResult.WriteTo(TextWriter writer)
   at System.Web.WebPages.WebPageBase.Write(HelperResult result)
   at System.Web.WebPages.WebPageBase.RenderSurrounding(String partialViewName, Action`1 body)
   at System.Web.WebPages.WebPageBase.PopContext()
   at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
   at RazorGenerator.Mvc.PrecompiledMvcView.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.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)
   at System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
   at System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
   at System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult)
   at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
   at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
   at System.Web.Mvc.HttpHandlerUtil.ServerExecuteHttpHandlerAsyncWrapper.<>c__DisplayClassa.<EndProcessRequest>b__9()
   at System.Web.Mvc.HttpHandlerUtil.ServerExecuteHttpHandlerWrapper.<>c__DisplayClass4.<Wrap>b__3()
   at System.Web.Mvc.HttpHandlerUtil.ServerExecuteHttpHandlerWrapper.Wrap[TResult](Func`1 func)
   at System.Web.Mvc.HttpHandlerUtil.ServerExecuteHttpHandlerWrapper.Wrap(Action action)
   at System.Web.Mvc.HttpHandlerUtil.ServerExecuteHttpHandlerAsyncWrapper.EndProcessRequest(IAsyncResult result)
   at System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride)
   at System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride)
   at System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage)
   at System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm)
   at System.Web.HttpServerUtilityWrapper.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm)
   at System.Web.Mvc.Html.ChildActionExtensions.ActionHelper(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues, TextWriter textWriter)
   at System.Web.Mvc.Html.ChildActionExtensions.Action(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues)
   at Sdl.Web.Mvc.Html.HtmlHelperExtensions.DxaEntity(HtmlHelper htmlHelper, EntityModel entity, Int32 containerSize) in C:\Users\l19548828\SourceCode\dxa-web-application-dotnet\Sdl.Web.Mvc\Html\HtmlHelperExtensions.cs:line 297
   at Sdl.Web.Mvc.Html.HtmlHelperExtensions.DxaEntities(HtmlHelper htmlHelper, Int32 containerSize) in C:\Users\l19548828\SourceCode\dxa-web-application-dotnet\Sdl.Web.Mvc\Html\HtmlHelperExtensions.cs:line 352
   at ASP._Areas_MyModule_Views_Region_Main_cshtml.Execute() in C:\Users\l19548828\SourceCode\my.web\Modules\My.Web.MyModule\obj\CodeGen\Areas\MyModule\Areas\MyModule\Views\Region\Main.cshtml:line 3
   at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
   at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()
   at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
   at RazorGenerator.Mvc.PrecompiledMvcView.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.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.<BeginInvokeAction>b__1c()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)

@jhorsman
Copy link
Contributor Author

After some more debugging we found what's causing this error in our implementation. The cause is twofold:

  1. User error; we used a Views\_ViewStart.cshtml in our web application project.
  2. DXA makes an not so intuitive assumption; DXA assumes the web application does not use a Views\_ViewStart.cshtml while this is common to have one in a .NET MVC site.

We fixed this by removing the Views/_ViewStart.cshtml from our site project, but I would still like to propose an improvement to prevent others running into the same issue.

DXA assumes there is no Views\_ViewStart.cshtml. The example Site project also does not have one. Instead, the ViewStart is in Views\Areas\Core\Views\Page.

If you do happen to put Views\_ViewStart.cshtml in your project, and an excption occurs. DXA will:

  1. load the EntityError.cshtml, SectionError.cshtml or Server.cshtml
  2. those in turn will try to load the ViewStart
  3. which in turn directs to the _Layout.cshtml which tries to use a page model which is not set.

In the log posted in an earlier comment you can see that something goes wrong with the view model mapping. What happens is that

  1. an ExeptionEnitity is loaded into the region model
  2. the entity view is rendered in the region view
  3. the entity view uses the ViewStart and the _Layout.cshtml which will raise an exception because it is expecting a PageModel instead of a ExecptionEntity.

I propose the following changes to DXA:

  1. Use PartialViewResult instead of ViewResult in HandleSectionErrorAttribute.cs. This will prevent the SectionError.cshtml and Server.cshtml` to load the ViewStart at all.
  2. Add @{ Layout = ""; } to the ServerError.cshtml so that it will not use Layout configured in the ViewStart.
  3. If (1) is not practical for reasons I don't foresee: add @{ Layout = ""; } to SectionError.cshtml and Server.cshtml` as well.

jhorsman pushed a commit to jhorsman/dxa-web-application-dotnet that referenced this issue Dec 22, 2016
jhorsman pushed a commit to jhorsman/dxa-web-application-dotnet that referenced this issue Dec 22, 2016
@rpannekoek
Copy link
Contributor

Internal Issue ID (for tracking purposes): CRQ-12795

@rpannekoek rpannekoek added this to the v2.2 milestone Dec 18, 2018
@rpannekoek rpannekoek removed this from the v2.2 milestone Jan 30, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants