问题
We have several environments:
- Development
- Azure
- On Prem
The Crystal Report pulls data from a SQL server, but the database is different depending on the environment.
There is a config file in the project called connectionStrings.config
and the connection string that we use for the website is stored there. The contents of the file looks like this:
<connectionStrings>
<add name="dataModel" connectionString="data source=...;initial catalog=...;user id=...;password=...;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>
To load the report I setup the following class:
public class CrystalReportUtil
{
static string ReportsDirectory = ConfigurationManager.AppSettings["ReportsDirectory"];
private static string ConnectionString = ConfigurationManager.ConnectionStrings["dataModel"].ConnectionString;
public static ReportDocument GetReport(string reportName)
{
var report = new ReportDocument();
var fileDirectory = $"{Utilities.GetProjectRoot()}/Reports";
if (System.Web.HttpContext.Current != null)
{
fileDirectory = System.Web.HttpContext.Current.Server.MapPath(ReportsDirectory);
}
string file = Path.Combine(fileDirectory, $"{reportName}.rpt");
if (!File.Exists(file))
{
throw new System.Exception($"Unable to find report file: {file}");
}
report.Load(file);
var builder = new SqlConnectionStringBuilder(ConnectionString);
var dataSource = builder.DataSource;
var user = builder.UserID;
var password = builder.Password;
var database = builder.InitialCatalog;
RecursivelyRemapConnection(report, user, password, dataSource, database);
report.VerifyDatabase();
return report;
}
private static void RecursivelyRemapConnection(ReportDocument report, string username, string password, string server, string database)
{
foreach (IConnectionInfo connection in report.DataSourceConnections)
{
connection.SetLogon(username, password);
connection.SetConnection(server, database, false);
}
report.SetDatabaseLogon(username, password);
foreach (Table table in report.Database.Tables)
{
table.LogOnInfo.ConnectionInfo.ServerName = server;
table.LogOnInfo.ConnectionInfo.DatabaseName = database;
table.LogOnInfo.ConnectionInfo.UserID = username;
table.LogOnInfo.ConnectionInfo.Password = password;
table.LogOnInfo.ConnectionInfo.IntegratedSecurity = false;
}
if (!report.IsSubreport)
{
foreach (ReportDocument subreport in report.Subreports)
{
RecursivelyRemapConnection(subreport, username, password, server, database);
}
}
}
}
The issue is that in my development environment, it is working just fine whereas in the other environments I get the following exception:
Log on failed. No error.
at CrystalDecisions.ReportAppServer.ClientDoc.ReportClientDocumentClass.VerifyDatabase()
at CrystalDecisions.ReportAppServer.ReportClientDocumentWrapper.VerifyDatabase()
at CrystalDecisions.CrystalReports.Engine.ReportDocument.VerifyDatabase()
I verified that the connection is changing in my development environment by doing the following:
- Creating a copy of my datasource
- In the designer, setting the datasource to the copied database
- Deleting the copy
- Previewing the report in the designer fails to load (as expected)
- Generating the report using my utility class
The last step successfully generates the report which tells me that the datasource is changing, otherwise I would expect a logon failure.
What makes this particularly frustrating is that some reports in the non-developing environments work fine whereas some are producing the exception. So I don't understand why it works for some, but not for all.
Update
If I change my connection string in my development environment to the connection string used in Azure or in the On-Prem, it still works in my development environment. I really don't believe that the issue is with my connection string, but then again I have no idea what is causing the logon failure at this point.
回答1:
After several days of looking into this, I finally found out what was causing the issue.
The particular report that was failing was using the MSOLEDBSQL
provider instead of SQLOLEDB
.
To fix the issue, I:
- Opened the Crystal Report in Visual Studio
- Right-clicked on the report
- Database > Set Datasource Location
- Expanded the properties of the current datasource
- Double-clicked on the provider
- Changed the value from
MSOLEDBSQL
toSQLOLEDB
- Reentered the logon credentials (even though they get changed at runtime)
- Saved the report
- Build the solution
- Republished the project
来源:https://stackoverflow.com/questions/65095676/crystal-reports-log-on-failed-in-different-environment