I have an aspx page that contains an ascx child control, and I'm finding that the OnLoad
handler is never happening on the child ascx control. Actually, no events are happening in the child or parent control, except for the OnUnload
event in the child control.
My page is called CrystalViewer.aspx
, inheriting from System.Web.UI.Page
, with an override for the OnLoadComplete
sub. This page contains the CrystalReport.ascx
as a child control.
Markup
<div>
<uc1:CrystalReport id="CrystalReport1" runat="server" />
</div>
My child control is called CrystalReport.ascx
, inheriting from PortalModuleBase
in the DotNetNuke.Entities.Modules
namespace. This child control contains a multiview where the first view lets you select parameters to pass to the report, and the second view contains the CrystalReportViewer
.
<asp:View ID="ViwReport" runat="server">
<CR:CrystalReportViewer ID="CrystalReportViewer1" runat="server" Width="350px" Height="50px" HasCrystalLogo="False" SeparatePages="True" />
</asp:View>
I have overloads for OnLoad
, OnUnload
, with logging in each of them.
When I navigate to http://localhost/portal/Modules/Reports/CrystalViewer.aspx?data=O%2b3zhvKVeiMG1qKIK6HGm0ONmAKh336xgBBOzfSVwqH%3d
locally, I get the following error.
NullReferenceException: Object reference not set to an instance of an object.
Reports.CrystalReport.OnUnload(EventArgs e) +401
System.Web.UI.Control.UnloadRecursive(Boolean dispose) +159
System.Web.UI.Control.UnloadRecursive(Boolean dispose) +322
System.Web.UI.Control.UnloadRecursive(Boolean dispose) +322
System.Web.UI.Page.UnloadRecursive(Boolean dispose) +23
System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +11538542
System.Web.UI.Page.ProcessRequest() +269
System.Web.UI.Page.ProcessRequest(HttpContext context) +167
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() + 625
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +270
This is a snippet of the OnUnload
override, showing how far the method gets before blowing up, because the controller variable is Nothing
.
Protected Overloads Overrides Sub OnUnload(ByVal e As EventArgs)
Using Log.UI.Trace("CrystalReport.OnUnload")
Log.UI.Send("RemoveHandler controller.ReportDocumentChanged, AddressOf ReportDocumentChanged")
Log.UI.Send("controller", controller)
RemoveHandler controller.ReportDocumentChanged, AddressOf ReportDocumentChanged
'^ blows up here on controller.ReportDocumentChanged because controller is Nothing
'... that is the last log message I see, so I'm sure that is what the error here is from
End Using
End Sub
I've been comparing the web.config from the client to one that works in dev and they are pretty much identical except for connection strings. I thought there might have been some Crystal Reports configuration we messed up, so we reinstalled it completely and we still get the same error.
I'm not sure where to look next, and I'm sort of waiting to hear how it looks after they restart the server so I'm asking this to see if anyone has seen something similar, where the OnLoad
events don't fire, but OnUnload
does. It just seems so weird that it would be trying to load something when it never loaded it in the first place, and I have no idea why it doesn't load anyway.
Edit: Our CrystalReport class inherits from MvcContainer(Of Controllers.OnDemandReportController)
, which inherits from DotNetNuke.Entities.Modules.PortalModuleBase
The OnLoad handler of the CrystalReport never fires, so it never calls the base classes OnLoad, so the controller for the CrystalReport class is Nothing
, and blows up.
I solved this today by modifying the OnUnload
code to call the controller initialization logic, so that it wouldn't get a NullReferenceException
, which exposed the root cause of why the OnLoad
handlers were never run.
There was an assembly binding redirect in the web.config, like the following
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
We use Crystal reports, and it was trying to call a method that exists in the 4.0 version of System.Web.Extensions
, that doesn't exist in the 3.5 version.
This is the post that showed me how to fix the error message I was seeing.