Crystal Reports客户端已传凭据仍弹出登录框问题排查
Crystal Reports部署至Server 2019后弹出登录框的解决方案
问题概述
Win10开发环境下Crystal Reports运行正常,但部署到Server 2019后,即便代码中传入数据库凭据,报表预览时仍弹出登录窗口。已安装x64 Crystal运行时及.NET 4.8,应用其他功能正常。尝试更换驱动(SQLNCLI11→MSOLEDBSQL)、切换至SQLOLEDB驱动、启用集成安全均未解决核心问题(SQLOLEDB虽无登录提示,但导致日期字段转为字符串,100+报表失效)。
核心排查点与修复方案
1. 覆盖子报表的登录信息
现有代码仅处理了主报表的表连接,若报表包含子报表,子报表的旧连接信息未更新会触发登录弹窗。需遍历所有子报表并同步连接配置:
// 遍历主报表下的所有子报表 foreach (ReportDocument subReport in cryRpt.Subreports) { Tables subTables = subReport.Database.Tables; foreach (CrystalDecisions.CrystalReports.Engine.Table subTable in subTables) { TableLogOnInfo subLogOnInfo = subTable.LogOnInfo; subLogOnInfo.ConnectionInfo = crConnectionInfo; subTable.ApplyLogOnInfo(subLogOnInfo); } }
2. 显式指定驱动类型
在配置ConnectionInfo时,明确指定驱动DLL名称,避免Crystal自动选择不兼容的驱动:
// 针对MSOLEDBSQL驱动补充配置 crConnectionInfo.DLLName = "MSOLEDBSQL.dll"; crConnectionInfo.ServerType = CrystalDecisions.Shared.CrServerTypeEnum.crServerTypeSQL;
3. 清理报表设计时的旧连接残留
打开问题报表的.rpt文件,在Crystal Reports设计器中操作:
- 进入「数据库」→「设置数据库位置」
- 将所有表(含子报表的表)的连接从SQLNCLI11替换为MSOLEDBSQL
- 保存报表后重新部署,消除设计阶段的旧连接缓存
4. 验证32/64位匹配
- 若为Web应用,确保Server 2019上的应用池设置启用32位应用程序=False,与x64 Crystal运行时兼容
- 项目编译选项设置为x64,避免运行时自动切换为32位导致驱动不匹配
5. 强制刷新表位置
在应用登录信息后,添加刷新表位置的代码,确保连接配置生效:
foreach (CrystalDecisions.CrystalReports.Engine.Table CrTable in CrTables) { crtableLogoninfo = CrTable.LogOnInfo; crtableLogoninfo.ConnectionInfo = crConnectionInfo; CrTable.ApplyLogOnInfo(crtableLogoninfo); // 强制更新表位置,覆盖旧连接 CrTable.Location = CrTable.Location; }
修改后的完整代码示例
private void generateReport() { string studyNum = txtStudyNum.Text.Trim().ToString(); ReportDocument cryRpt = new ReportDocument(); TableLogOnInfo crtableLogoninfo = new TableLogOnInfo(); ConnectionInfo crConnectionInfo = new ConnectionInfo(); Tables CrTables; var appPath = AppDomain.CurrentDomain.BaseDirectory; string reportName = "SponserSearch.rpt"; var relativePath = System.IO.Path.Combine("StudyManagement", "Reports", reportName); appPath = System.IO.Path.Combine(appPath, relativePath); cryRpt.Load(appPath); // 配置连接信息,显式指定驱动 crConnectionInfo.ServerName = Properties.Settings.Default.strDBServer; crConnectionInfo.DatabaseName = Properties.Settings.Default.strDBName; crConnectionInfo.UserID = Properties.Settings.Default.strDBUser; crConnectionInfo.Password = Properties.Settings.Default.strDBPass; crConnectionInfo.IntegratedSecurity = false; crConnectionInfo.DLLName = "MSOLEDBSQL.dll"; crConnectionInfo.ServerType = CrystalDecisions.Shared.CrServerTypeEnum.crServerTypeSQL; // 处理主报表表登录信息 CrTables = cryRpt.Database.Tables; foreach (CrystalDecisions.CrystalReports.Engine.Table CrTable in CrTables) { crtableLogoninfo = CrTable.LogOnInfo; crtableLogoninfo.ConnectionInfo = crConnectionInfo; CrTable.ApplyLogOnInfo(crtableLogoninfo); CrTable.Location = CrTable.Location; } // 处理子报表登录信息 foreach (ReportDocument subReport in cryRpt.Subreports) { Tables subTables = subReport.Database.Tables; foreach (CrystalDecisions.CrystalReports.Engine.Table subTable in subTables) { TableLogOnInfo subLogOnInfo = subTable.LogOnInfo; subLogOnInfo.ConnectionInfo = crConnectionInfo; subTable.ApplyLogOnInfo(subLogOnInfo); subTable.Location = subTable.Location; } } cryRpt.SetParameterValue("@SponsorInfo", studyNum); crystalViewer.ViewerCore.ReportSource = cryRpt; }
内容的提问来源于stack exchange,提问作者Christopher Parlato
相关产品推荐
相关产品推荐

