13
votes

At the time being I'm tired of trying to fix this issue in Crystal Reports. We have 3 environments, development, deployment in production (shared) and local computers. If I don't match exactly the production environment in development Crystal Reports never shows reports. I made a huge research through all the forums and I tried every single solution. It doesn't matter what I try, when I try to Apply a new log-on information it never works, it simply fails at the end when I cycle tables to test connection:

foreach (CrystalDecisions.CrystalReports.Engine.Table table in document.Database.Tables)
{
    TableLogOnInfo tableLogOnInfo = table.LogOnInfo;

    tableLogOnInfo.ConnectionInfo = info.ConnectionInfo;
    table.ApplyLogOnInfo(tableLogOnInfo);
    if (!table.TestConnectivity())
    {
        string msg = ("Failed to apply log in info for Crystal Report");
        throw new ApplicationException(msg);
    }
}

If I change user or password for an invalid one it fails previously in SetConnection or SetDatabaseLogon. I knew there was an error that I can't change from integrated security to non-integrated security, so I set my own database to use regular user and password credentials.

I can clearly see connections are not set because in my development computer I set an invalid password, it fails but if I continue I see the report. In production computers it always fails and it doesn't show the report either (skipping the error for debugging purposes). So seems connection is hard-coded and it can't be changed.

Any ideas? I can publish all the code to change connection information but I think it doesn't worth, it's well known.

Solution

Like many people told me, there isn't a single solution. It seems depending on the Crystal Reports version it works different. In my case the following solution worked for Crystal Reports 10.5.3700.

public static void CrystalReportLogOn(ReportDocument reportParameters, string serverName, string databaseName, string userName, string password)
{
    TableLogOnInfo logOnInfo;
    ReportDocument subRd;
    Sections sects;
    ReportObjects ros;
    SubreportObject sro;

    if (reportParameters == null)
    {
        throw new ArgumentNullException("reportParameters");
    }

    try
    {
        foreach (CrystalDecisions.CrystalReports.Engine.Table t in reportParameters.Database.Tables)
        {
            logOnInfo = t.LogOnInfo;
            logOnInfo.ReportName = reportParameters.Name;
            logOnInfo.ConnectionInfo.ServerName = serverName;
            logOnInfo.ConnectionInfo.DatabaseName = databaseName;
            logOnInfo.ConnectionInfo.UserID = userName;
            logOnInfo.ConnectionInfo.Password = password;
            logOnInfo.TableName = t.Name;
            t.ApplyLogOnInfo(logOnInfo);
            t.Location = t.Name;
        }
    }
    catch
    {
        throw;
    }

    sects = reportParameters.ReportDefinition.Sections;
    foreach (Section sect in sects)
    {
        ros = sect.ReportObjects;
        foreach (ReportObject ro in ros)
        {
            if (ro.Kind == ReportObjectKind.SubreportObject)
            {
                sro = (SubreportObject)ro;
                subRd = sro.OpenSubreport(sro.SubreportName);
                try
                {
                    foreach (CrystalDecisions.CrystalReports.Engine.Table t in subRd.Database.Tables)
                    {
                        logOnInfo = t.LogOnInfo;
                        logOnInfo.ReportName = reportParameters.Name;
                        logOnInfo.ConnectionInfo.ServerName = serverName;
                        logOnInfo.ConnectionInfo.DatabaseName = databaseName;
                        logOnInfo.ConnectionInfo.UserID = userName;
                        logOnInfo.ConnectionInfo.Password = password;
                        logOnInfo.TableName = t.Name;
                        t.ApplyLogOnInfo(logOnInfo);
                    }
                }
                catch
                {
                    throw;
                }
            }
        }
    }
}

Every other solution I tried didn't work at all.

1
I had a similar problem and solution except I had to put the t.Location = t.Name; into its own loop. For some reason it did not apply to all of the tables inside the first loop only the last.user18443
Good to know, it didn't happen to me, as I said, solutions depend on the version. It's very tricky how it works! Thanks for sharing your solution.Maximiliano Rios
I have tryed your approach but to no avail. I still get the error "Log on Failed". The same code works on 32 bit windows 7, but on 64 bit it gives me that error. I do not know what is the problem. :(Aaron C

1 Answers

3
votes

I had similar issue. It matters which version of Crystal reports you are using. For some versions if you set the table location in addition of ApplyLogOnInfo the report will work.

Are you trying to set the report connection during the runtime or you have also separate reports for the different environments ? We found that it is easier to create different report environments (but we have just 2: development and production). This allowed us to set once the connection information - when we move the reports from development to production. We had few in house developed tools, which were taking care for the different report versions. Now we are using this 3rd party tool : http://www.r-tag.com/Pages/CRDataSource.aspx It seems to handle all the versions correctly, but works just for one connection per report.