
我跟大家说,做程序员这行,没少跟各种“历史遗留问题”打交道。ReportViewer这玩意儿,就是其中一个大坑。我那会儿接了个外包的活儿,一个老客户的系统,功能都跑得好...
我跟大家说,做程序员这行,没少跟各种“历史遗留问题”打交道。ReportViewer这玩意儿,就是其中一个大坑。我那会儿接了个外包的活儿,一个老客户的系统,功能都跑得好好的,就差几个新报表要加上去。
我当时信心满满,觉得不就是拖个控件,绑个数据源的事儿吗?结果刚一上手,就卡住了。
我在本地环境里弄了个报表设计文件(RDLC),拖进去,双击设置,跑起来。结果,控制台直接给我甩脸色,一个经典错误:“找不到程序集”。唉呀妈呀,哪个程序集?我明明都引用了最新的NuGet包了呀!
我把项目里的引用对着老项目里的一条条看,对比版本号,发现了一个大问题。老系统用的是好几年前的ReportViewer版本,我随手装的NuGet包是新的。这两套东西打架了!
这回控件倒是出来了,但一看报表内容,白板一块,数据?全给我吞了!

数据出不来,这可比找不到程序集还让人头疼。我对着代码一行行地撸,心想是不是我绑定数据源的逻辑写错了?
我调试进去,盯着数据看了半天,数据是实实在在查出来了,但就是不往报表里填。
我在网上各种搜,翻了好几个国外论坛的帖子,才发现一个不起眼的细节,资深老鸟估计都知道,但我那会儿经验尚浅:

我马上在代码里加上了关键的两行:设置新的数据源,然后调用一下那个至关重要的 RefreshReport() 方法。
我把代码一存,按下F5,屏幕上终于,清清楚楚地,把数据给我吐出来了!那时候的感觉,简直比发工资还爽。
经过这回折腾,我总结出了一套对付ReportViewer的“三板斧”,以后再遇到,我都是先用这几招试探试探它:
第一招:版本一致性! 别想当然装最新的NuGet包。一定要去检查服务器上或者目标环境的DLL版本。如果必须使用新版本,老实地在 * 或 * 里面配置好程序集绑定重定向(Assembly Binding Redirect)。不然它就是个定时炸弹。
第二招:数据刷新要跟上! 用本地模式跑报表,数据源赋值完了之后,记得刷新。很多人会忘记这一步,尤其是在异步操作或者复杂的事件处理里。数据再对,你不叫它,它就不动。
第三招:权限和模式要对! 有些环境因为权限问题会卡死。如果不是必须,尽量使用 LocalReport 模式,直接本地处理数据,少去跟远端服务器模式(Remote Mode)折腾那些复杂的配置。
我之所以对这个ReportViewer的坑记得这么清楚,是因为当时接这活儿的时候,我正准备给我妈换个助听器,钱上有点紧。我本以为这报表是个小活儿,能快点搞定,结果硬是被这几个低级错误拖了整整一个通宵,一觉都没睡。那天早上我顶着两个黑眼圈,把成功的截图发给客户,收到转账的那一刻,感觉这黑眼圈值了。
所以说,技术细节是死的,但解决问题的经验是活的。折腾多了,你自然就知道什么地方可能有鬼了。下次再遇到类似的坑,别慌,先回忆一下当初被折腾的经历,也许答案就在那个角落里等着你。