on 04-14-2014 11:58 AM
hi,
I am trying to run a report from a WCF service application, and then render it in PDF Format to a caller WPF application. But I cant get it! In more detail, this is what my app should do
1. from WPF, call a web service procedure, pass a report name, report path and parameters. Report is store at the same server where Web Service is installed
2. WCF procedure loads report, set parameters, retrieve data from DB and renders it as an array of bytes
3. WPF gets the array, save it into a PDF file, then open it.
this is the code of the WCF procedure.
Function DownloadCRReport(codEnte As String, connString As String, reportDir As String, reportName As String, Parameters As Dictionary(Of String, Object)) As Byte() Implements IGesiService.DownloadCRReport
Try
Dim bytes As Byte()
Dim infile As BinaryReader
Dim fs As FileStream
Dim rep As New ReportDocument
Dim RepAddress As String
logPath = reportDir & "log\"
sb = New StringBuilder()
timestamp = Now.Year.ToString & Now.Month.ToString & Now.Day.ToString & Now.Hour.ToString & Now.Minute.ToString & Now.Second.ToString
logFileName = timestamp & "_" & reportName & ".txt"
logFile = New StreamWriter(logPath & logFileName, FileMode.CreateNew)
logFile.WriteLine("----
Date and time: " & Now.ToString & " -
")
If My.Computer.FileSystem.FileExists(reportDir & reportName & ".rpt") = False Then
Throw New Exception("file RPT non found in: " & reportDir)
End If
RepAddress = reportDir & reportName & ".rpt"
logFile.WriteLine("rep address: " & RepAddress)
rep.Load(RepAddress, OpenReportMethod.OpenReportByDefault)
logFile.WriteLine("load rep")
If rep.DataSourceConnections.Count > 0 Then
rep.DataSourceConnections.Item(0).SetLogon("usr", "pwd")
logFile.WriteLine("data source connection")
End If
For Each i In Parameters
rep.SetParameterValue(i.Key, i.Value)
logFile.WriteLine("param: " & i.Key & " - " & i.Value)
Next
Try
fs = rep.ExportToStream(ExportFormatType.PortableDocFormat)
logFile.WriteLine("export to stream")
infile = New BinaryReader(fs)
logFile.WriteLine("created binaryreader")
bytes = infile.ReadBytes(CInt(fs.Length))
logFile.WriteLine("render pdf. fine")
logFile.Close()
Return bytes
Catch ex As Exception
logFile.WriteLine("vbCrLf & ex.Message & vbCrLf & ex.InnerException.Message)
logFile.Close()
Return Nothing
End Try
Catch ex As Exception
logFile.WriteLine("vbCrLf & ex.Message & "-" & vbCrLf & ex.InnerException.Message)
logFile.Close()
Return Nothing
End Try
End Function
I detected that error occurs on rep.ExportToStream(ExportFormatType.PortableDocFormat). I should point out that the same procedure works under WPF application. In the WCF server I installed CR Runtime engine for .NET framework (13.0.9.1312) and CR version for Microsoft Visual Studio (same version). Moreover, all DB operations are stored into the report, so I should not pass any dataset, just parameters.
Anyway, just to begin, I tried to call a simple report with just two string parameters and no queries, but I alwais get error ("An exception of type 'System.NullReferenceException' occurred in MyApp... Object reference not set to an instance of an object)!
How can I make it work? thanks for help
A good test will be with a report that has not database connection at all. E.g.; create a new report, add a text box with a string: "Hello World". Save. Run. Does this report throw the same error? Alternatively, use a "saved data" report. But be sure to comment out any logon code and parameter code. E.g.; all you want is load report and export to pdf.
- Ludek
Senior Support Engineer AGS Product Support, Global Support Center Canada
Follow us on Twitter
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
hi Ludek,
I did as you suggested: empty report, with just text boxes, no parameters, no DB connection. Same result: on ExportToStream, the web service crashes. even the log file results empty, so I cant detect why error occurred.
So, I suppose that some CR library is missing or is not registered on the server computer, which is a mirror of the development one (Windows 7 64 bit, CR runtime for Microsoft .Net, CR version for Visual Studio 2013; only CR designer is not installed).
after a long time searching and testing, maybe I came to a solution.
bug 1, ie crashing on ExportToStream, was caused by a trivial type mismatch (saving to a FileStream instead of the expected IO.Stream).
bug 2, ie failing to connect to DB, occurred because CR runtime was unable to locate a tnsnames.ora file. I resolved by adding an environment variable, TNS_ADMIN, pointing to my Oracle Client home.
So, now my web service is able to call the report and convert it into a stream. Another open issue would be call a report and change the database connection, because it may not match with the connection used at design time. It seems that
rep.DataSourceConnections.Item(0).SetLogon("usr", "pwd") is not enough to achieve this. any suggestion is appreciated.
hi Ludek,
Im trying to change DB connection info at runtime for all of the report tables. this is the code I used in my Web Service
Function DownloadCRReport(...)
....
If rep.DataSourceConnections.Count > 0 Then | |
Dim conn As New ConnectionInfo | |
Dim tabLogon As TableLogOnInfo | |
conn.ServerName = "10.10.15.90" 'IP address of DB server | |
conn.DatabaseName = "MyDB" 'Database name as set in TNSNAMES.ORA | |
conn.UserID = "newuser" | |
conn.Password = "newpwd" | |
For Each t As Table In rep.Database.Tables | |
tabLogon = t.LogOnInfo | |
tabLogon.ConnectionInfo = conn | |
t.ApplyLogOnInfo(tabLogon) | |
logFile.WriteLine("changed logon tab. " & t.Name) | |
Next | |
rep.Refresh() | |
logFile.WriteLine("changed data source connection") | |
End If |
'set parameters | |
If Not IsNothing(Parameters) Then | |
For Each i In Parameters | |
rep.SetParameterValue(i.Key, i.Value) | |
logFile.WriteLine("set parameter" & i.Key & " - " & i.Value) | |
Next | |
End If | |
fs = rep.ExportToStream(ExportFormatType.PortableDocFormat) | |
.... |
End Function
that comes to an error on rep.ExportToStream: "Unable to access database".
Running web service in debug mode, I noticed that, after t.ApplyLogonInfo(tabLogon), the new ConnectionInfo has "password" property empty. Maybe this could cause the error, or is there some mistake in the new connectioninfo?
Interesting...
The code looks really good and should work fine. If there are subreports in the report, see if you can test without a subreport.
Other than that, a small win app will be interesting to test with. Just copy and paste the same code into the win app and rather than exporting to stream, send the report to the CR viewer. does that work? At the very least, this should give you better error messages.
- Ludek
things are becoming too strange.
First, I created a new simple report using OLE DB (Oracle Provider for OLE DB) driver instead of Server Oracle Driver to connect to DB.
Then I rewrote function DownloadCRReport changing the code to set DB Connection
Function DownloadCRReport(...)
....
If rep.DataSourceConnections.Count > 0 Then | |
rep.DataSourceConnections.Item(0).SetLogon("schema1", "pwd") 'first attempt. | |
'rep.DataSourceConnections.Item(0).SetLogon("schema2","pwd") 'connect to another schema | |
logFile.WriteLine("changed data source connection") | |
End If |
'set parameters | |
If Not IsNothing(Parameters) Then | |
For Each i In Parameters | |
rep.SetParameterValue(i.Key, i.Value) | |
logFile.WriteLine("set parameter" & i.Key & " - " & i.Value) | |
Next | |
End If | |
fs = rep.ExportToStream(ExportFormatType.PortableDocFormat) | |
.... |
End Function
Then I did 2 tests.
1. I skipped web service and copied the code into a local (WPF) procedure, changing . It works, both with user "schema1" and user "schema2"
2. I reused Web Service running in "Local" mode. ie, I changed app.config file putting
<endpoint address="http://localhost:65247/WebService.svc"....>
instead of
<endpoint address="http://10.10.15.90/MyWebService/WebService.svc"...> as it should be.
and this works too!
So, the only case not working is when I try to point to the remote web service, and I cant understand why.
Note that both WebService and DB are hosted in the remote server. I even installed a copy of my app in the remote server, obtaining the same behavior I descripted above. I guess some dll is missing, but I dont know what.
well, now I got to make web service work. I shared the folder where TNSNAMES.ORA is located, and gave read privileges to everyone. I published my app and asked some people to run reports from several computers, some of those not have CR Runtime installed. They are able to read reports as PDF file. great!
thank you ludek for your help.
User | Count |
---|---|
83 | |
24 | |
12 | |
9 | |
7 | |
6 | |
5 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.