I have come across a very strange exception when using Crystal Reports XI for dot net. I'm currently developing a reporting service in VB.Net for an enterprise application. The service is hosted in the main application as a plugin/add-in using System.AddIn (aka Managed Add-in Framework or MAF). The main application utilizes Win Forms, and will be hosting controls provided by my add-in in a WPFElementHost.
The add-in resides in it's own app domain and passes WPF controls using NativeHandleContracts from the add-in app domain, to the host app domain where they are bound at runtime to the WPFElementHost.
The WPF control the add-in provides has a Crystal Report Viewer Control in it. Up to this point, everything works fine. I can create nearly any WPF control in my Add-in and it works flawlessly in the host application. This falls apart as soon as I try and attach a report to the viewer.
First I tried using and ADO.Net DataSet as my data schema to build my report against. Whenever this would try and load into the report viewer, crystal reports would throw an exception that the schema didn't exist. This was caused because for some reason crystal report want's to look in the host applications app domain, as well as namespace for the schema. However The schema exists in an entirely different app domain and namespace. I tried embedding the schema as a resource, and copying local. With no success I moved on to using .Net Objects.
With .Net Objects I created an XML document that the report is designed against. This worked fine and allowed me to pass my report and view it in the host application. This is where I am stuck at the moment. Whenever I try and supply a DataSource for the report Crystal Reports throws a null reference exception in the crdb_adoplus.dll which is SAP's DLL and gives me no indication of what caused the exception. All of my objects are properly instantiated, the report, viewer, wpf element host, and the wpf control. My dataset, which is served using entity framework, is being converted to a DataSet so there are no nullable types in it, only dbnull values. There is no reason this exception should be throwing at this point. No additional output is provided other than the exception being thrown.
Additionally, the report object that is created will have portions of it time out during this loading process. This will happen without any exceptions or errors of any kind being thrown.
Here is the code that is retrieving the data, attempting to bind data to the report, and binding the report to the viewer.
Try
Dim messages As String = Nothing
If report Is Nothing Then
report = New BOMPartsListWithStandard
End If
Using conn = BOMReportingService.BOMReportingServiceClient.CreateConnection()
Dim dataSet As DataSet = conn.Proxy.GetBOMTreePartsListElements(5339, messages).ToDataSet
report.SetDataSource(dataSet)
End Using
reportViewer.ViewerCore.ReportSource = report
reportViewer.ViewerCore.RefreshReport()
Debug.WriteLine($"Created and attached report succesfully. With {IIf(String.IsNullOrEmpty(messages), "no messages.", messages)}")
Catch ex As Exception
Debug.WriteLine(ex.ToString)
End Try
The report.SetDataSource(dataSet)
bit of code is where the exception is being thrown.
Am I overlooking somthing obvious? Is there a way to convince Crystal Reports to use an ADO.Net DataSet in the correct app domain so I can get away from the XML issue?
This add-in needs to exist in a separate app domain, or process, so that it can be unloaded and reloaded dynamically at runtime. This is a requirement for the system. It also needs to be self contained, so I can't do anything on the host side of the application, it all must operate within the add-in.
Thanks in advance for the help.