Search code examples
c#iiscrystal-reports

Deploying an app with Crystal Reports in IIS


I am trying to deploy an app that I used Crystal Reports in. I want to say that it works on local host as I am using IIS Express and in staging I am using IIS. This is the main difference that I can think of but just to be sure I want to write out the entire process that have done.

  1. Build Report in Visual Studio
  2. Create ODBC Connection on local host
  3. Run Report in localhost - it works
  4. publish MVC app
  5. add ODBC connection with same name on server
  6. copy report to correct location on IIS server
  7. run app and report app works report doesn't.

The log that I am getting is:

FATAL 2018-08-28 03:22:30,923 37280ms Log Service GenerateReport - Exception during StringFormat: Index (zero based) must be greater than or equal to zero and less than the size of the argument list. Generate Reports at: 8/28/2018 3:22:30 AM, Exception: CrystalDecisions.CrystalReports.Engine.InternalException: Failed to open the connection. QuoteReport 5092_4216_{0FAD9DBD-DCD7-4158-816D-56895A79B362}.rpt Details: [Database Vendor Code: 4060 ] ---> System.Runtime.InteropServices.COMException: Failed to open the connection. QuoteReport 5092_4216_{0FAD9DBD-DCD7-4158-816D-56895A79B362}.rpt Details: [Database Vendor Code: 4060 ] at CrystalDecisions.ReportAppServer.Controllers.ReportSourceClass.Export(ExportOptions pExportOptions, RequestContext pRequestContext) at CrystalDecisions.ReportSource.EromReportSourceBase.ExportToStream(ExportRequestContext reqContext) --- End of inner exception stack trace --- at CrystalDecisions.ReportAppServer.ConvertDotNetToErom.ThrowDotNetException(Exception e) at CrystalDecisions.ReportSource.EromReportSourceBase.ExportToStream(ExportRequestContext reqContext) at CrystalDecisions.CrystalReports.Engine.FormatEngine.ExportToStream(ExportRequestContext reqContext) at CrystalDecisions.CrystalReports.Engine.ReportDocument.ExportToStream(ExportOptions options) at CrystalDecisions.CrystalReports.Engine.ReportDocument.ExportToStream(ExportFormatType formatType) at QuickQuote.Controllers.ReportsController.GenerateReport(Int32 reportId, String json) in C:\Users\James\Source\Repos\QuickQuote3\QuickQuote\Controllers\ReportsController.cs:line 84{}

Can someone please tell me what my issue is? I have google this error and I don't understand what my issue is.

try
{ 
    var stream = _reportBuilder.BuildReport(dataSet, report, filePath, parameters);
    stream.Seek(0, SeekOrigin.Begin);

    return File(stream, "application/pdf", $"Quote{report.Name}-{DateTime.Now}.pdf");
}
catch (Exception e)
{
    _loggingService.FatalFormat($"Generate Reports at: {DateTime.Now}, Exception: {e}");
    throw;
}

Inside reportBuilder.BuildReport is where it is breaking. I'm sure that it is this line:

var stream = reportDocument.ExportToStream(ExportFormatType.PortableDocFormat);

BuildReport method:

public Stream BuildReport(DataSet dataSet, Report report, string path, string parameters)
{
    var reportDocument = new ReportDocument();
    reportDocument.Load(path);
    reportDocument.SetDataSource(dataSet);
    AddParametersToReport(ref reportDocument, report, parameters);
    return reportDocument.ExportToStream(ExportFormatType.PortableDocFormat);
}

Solution

  • The exception message is Failed to open the connection.

    Verify if System Data Sources are set up correctly in ODBC Data Source Administrator (for both 32-bit and 64-bit).

    You may get Database logon failed error, as credentials specified in .rpt file might be invalid for the database. The solution is to provide database credentials in code:

    public Stream BuildReport(DataSet dataSet, Report report, string path, string parameters)
    {
        try
        {
            var reportDocument = new ReportDocument();
            reportDocument.Load(path);
            reportDocument.SetDataSource(dataSet);
            AddParametersToReport(ref reportDocument, report, parameters);
    
            // Set database credentials
            reportDocument.SetDatabaseLogon("dbUsername", "dbPassword");
    
            return ReportDocument.ExportToStream(ExportFormatType.PortableDocFormat);
        }
        catch(Exception ex)
        {
            _loggingService.FatalFormat($"Exception: {ex}");
            throw;
        }
    }