cancel
Showing results for 
Search instead for 
Did you mean: 

how to run a report from WCF

ciceroan
Participant
0 Kudos

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



Accepted Solutions (1)

Accepted Solutions (1)

former_member183750
Active Contributor
0 Kudos

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

ciceroan
Participant
0 Kudos

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).

ciceroan
Participant
0 Kudos

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.

former_member183750
Active Contributor
0 Kudos

I believe .SetLogon has an overload where you can specify a new server and database. As the code is, the report will want to use the server and db it was created off of.

- Ludek

ciceroan
Participant
0 Kudos

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?

former_member183750
Active Contributor
0 Kudos

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

ciceroan
Participant
0 Kudos

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.

ciceroan
Participant
0 Kudos

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.

Answers (0)