徹底解決水晶報表中登陸的錯誤 - 中國WEB開發者網絡 (http://www.webasp.net) -- 技術教程 (http://www.webasp.net/article/) --- 徹底解決水晶報表中登陸的錯誤 (http://www.webasp.net/article/18/17006.htm) |
| -- 作者:未知 -- 發佈日期: 2005-03-15 |
| 大家在基於webform中使用水晶報表時如果簡單的按照網上「阿刀」的做法,肯定會提示你:登陸失敗。
對於這個問題,斑竹我花了整整一天的時間研究水晶報表的幫助文件,終於得到解決方案。 我不是一個保守的人,我相信有很多的網友正和我一樣在花費精力在研究這個問題,我不願意大家再和我一樣白白的花費精力。 下面是我實現該方案的幾個步驟。大家不要著急,慢慢的看下去會對你有很大的幫助。 步驟一:看示例文件 水晶報表自帶一個示例文件,數據庫是access(不帶密碼的)。我首先運行示例文件(基於webform和winform)結果顯示了正確的報表,正如「飛刀」的示例。 於是,我自己建立了一個報表文件和.aspx文件,結果顯示登陸失敗!可是我把報表文件換成示例的報表文件,不再出錯。 問題出在什麼地方?難道是報表格式文件有關於登陸權限的設置?通過跟蹤、調試,我對比分析我的報表文件和示例報表文件,沒有發現任何的不同。看來問題不在報表文件。 是數據庫的問題?我建立一個access結果還是登陸失敗! 不是數據庫的問題(我自己的數據庫是未帶密碼的access,幫助中的數據庫也是如此)?也不是報表格式文件的問題(我仔細分析了兩者的原代碼是相同的)? 那麼問題出現在什麼地方?我白思不得其解! 步驟二:找幫助文件 於是我再次求助於幫助。我翻遍了水晶報表的幫助,終於找到「 訪問安全數據庫 [C#]」字樣,發現這裡有下面的一段話: 通過 Crystal Reports for Visual Studio .NET 訪問安全數據庫的過程在 Web 窗體和 Windows 窗體之間有所不同。在 Windows 窗體中,對話框自動提示用戶輸入用戶名和密碼(測試很容易成功)。而在 Web 窗體中,您需要設計一個表單以從用戶獲取該信息。對於這兩種情況,均可使用代碼來指定用戶名和密碼,從而為應用程序的所有用戶提供相同的安全等級。 於是我對同樣的數據庫(先是用幫助示例中的access數據庫,後來用自己建立的access數據庫)。發現對於同一個報表文件,對於winform能顯示成功,而對於webform則仍然顯示登陸失敗!於是我有點明白上面的意思! 看來問題是出在權限的設置上。 步驟三:研究幫助,終於成功! 在幫助裡我找到「設置數據庫登錄參數」字樣,裡面提供了一些後來發現是非常有用的信息: 下列示例說明如何將登錄參數傳遞到報表的表中。該示例使用到某個安全的 SQL Server 數據庫的連接。 啟動一個新項目 向窗體添加一個「按鈕」和四個「文本框」控件。 將「文本框」控件分別命名為:serverNameTxt、dbNameTxt、userNameTxt 和 passwordTxt。 雙擊「按鈕」控件以指定 Click 事件的代碼。根據所用語言插入適當的代碼。 [C#] // 聲明所需變量。 TableLogOnInfo logOnInfo = new TableLogOnInfo (); int i = 0; // 對報表中的每個表依次循環。 for (i=0;i == Report.Database.Tables.Count - 1;i++) { // 設置當前表的連接信息。 logOnInfo.ConnectionInfo.ServerName = serverNameTxt.Text; logOnInfo.ConnectionInfo.DatabaseName = dbNameTxt.Text; logOnInfo.ConnectionInfo.UserID = userNameTxt.Text; logOnInfo.ConnectionInfo.Password = passwordTxt.Text; Report.Database.Tables [i].ApplyLogOnInfo (logOnInfo); } 注意 受密碼保護的 Microsoft Access 和 Paradox 等 PC 數據庫也使用該方法,但 LogOnInfo.ServerName 和 LogOnInfo.DatabaseName 要保留為空。 於是我仿照這個樣子,嘗試了一下,出錯提示:沒有發現TableLogOnInfo 和Report。 後來我發現TableLogOnInfo 是屬於CrystalDecisions.Shared 命名空間的成員。於是我添加引用: using CrystalDecisions.Shared ; 這次問題出現在Report。 Report?這是個什麼東西,我查遍了所有的幫助,並沒有這個函數或類! [說真的!這個問題難到了我很長的時間!一直在查找Report到底是個什麼東西!水景報表公司也真是的,幫助也不寫得詳細一點!該打!!!] 最終我終於發現Report只是一個用戶定義的對象,不是系統本身的對象。 在我困惑的時候,突然我想,為什麼不看看Report後面的DataBase,這是個什麼東西,終於問題解決了,在幫助裡找到如下信息 ReportDocument oRpt = new ReportDocument(); Report屬於DocumentCrystalDecisions.CrystalReports .Engine 類的成員。 修改代碼:並添加引用 using CrystalDecisions.Shared ;//負責解釋TableLogOnInfo類 using CrystalDecisions.CrystalReports .Engine ;//負責解釋ReportDocument類private void Page_Load(object sender, System.EventArgs e) { TableLogOnInfo logOnInfo = new TableLogOnInfo (); //這裡必須事先申明一個ReportDocument對像 Report,同時加載數據報表 ReportDocument oRpt = new ReportDocument(); oRpt.Load("c:\\inetpub\\wwwroot\\exer\\pagelet\\crystal\\cr1.rpt");//修改為你自//己的正確位置 //建立安全信息 //受密碼保護的 Microsoft Access 和 Paradox 等 PC 數據庫也使用該方法,但 LogOnInfo.ServerName //和 LogOnInfo.DatabaseName 要保留為空 logOnInfo.ConnectionInfo.ServerName = "www"; logOnInfo.ConnectionInfo.DatabaseName = "archives"; logOnInfo.ConnectionInfo.UserID = "sa"; logOnInfo.ConnectionInfo.Password = "123456"; oRpt.Database .Tables [0].ApplyLogOnInfo (logOnInfo); //建立.rpt文件與CryStalReportviewer文件之間的連接 CrystalReportViewer1.ReportSource = oRpt; } 報表文件終於出現! 哇,我好高興,禁不住站起來伸了個懶腰! 步驟四:最終的完整版的代碼 上面的代碼不具有系統可擴充和靈活性。缺點有二: (1)、數據報表格式文件是採用絕對路徑 (2)、數據庫訪問權限的設置一旦設定,在最終發佈是無法修改的,特別是客戶的SQL SERVER服務器不可能和你調試的程序環境是一樣的 基於這個考慮。引進兩個比較好的東西: (1)、Server.Mappath函數 (2)、讀取web.config(本示例同時告訴你如何操作web.config配置文件) 最終修改如下:(完整代碼)數據庫為sql server2000 using CrystalDecisions.Shared ;//負責解釋TableLogOnInfo類 using CrystalDecisions.CrystalReports .Engine ;//負責解釋ReportDocument類 private void Page_Load(object sender, System.EventArgs e) { TableLogOnInfo logOnInfo = new TableLogOnInfo (); //這裡必須事先申明一個ReportDocument對像 Report,同時加載數據報表 ReportDocument oRpt = new ReportDocument(); //獲取.rpt文件真實路徑 string path1,path2; path1=Server.MapPath ("\\exer\\pagelet"); path2=path1+"\\crystal\\cr1.rpt"; //oRpt.Load("c:\\inetpub\\wwwroot\\exer\\pagelet\\crystal\\cr1.rpt"); oRpt.Load (path2); //從web.config中獲取logOnInfo參數信息 string a,b,c,d; //獲取ServerName a=System.Configuration .ConfigurationSettings .AppSettings ["servername"]; //獲取DatabaseName b=System.Configuration .ConfigurationSettings .AppSettings ["database"]; //獲取UserId c=System.Configuration .ConfigurationSettings .AppSettings ["userid"]; //獲取password d=System.Configuration .ConfigurationSettings .AppSettings ["pass"]; //設置logOnInfo參數 logOnInfo.ConnectionInfo.ServerName = a; logOnInfo.ConnectionInfo.DatabaseName = b; logOnInfo.ConnectionInfo.UserID = c; logOnInfo.ConnectionInfo.Password = d; oRpt.Database .Tables [0].ApplyLogOnInfo (logOnInfo); //建立.rpt文件與CryStalReportviewer文件之間的連接 CrystalReportViewer1.ReportSource = oRpt; } 整個演示的操作過程說明: 1、 在解決方案資源管理器裡,你需要存放報表文件處,添加新項:CrystalReport報表,起名為cr1.rpt 2、 在隨後出現的「報表專家」中選擇數據源時,請務必選擇OLE DB,然後根據你的數據庫的要求選擇響應的驅動引擎: SQL SERVER:Microsoft OLE DB Provider for SQL server Access:Microsoft Jet.4.0 3、 輸入正確的數據庫連接,這一步大家一般的情況下不會出錯! 4、 建立數據報表,並保存cr1.rpt文件 5、 打開webform1.aspx。添加crystalreportviewer控件:名稱為:CrystalReportViewer1 6、 在webform1.aspx.cs中的page_load事件中添加上面的代碼: (注意:引用千萬不要忘了!) ***************************************************** 下面是web.config中與本內容有關的細節 <appSettings> <add key="servername" value="www"/> <add key="database" value="archives"/> <add key="userid" value="admin"/> <add key="pass" value="123456"/> </appSettings> ***注意這裡的<add key="pass" value="123456"/>是pass,所以他必須與 //獲取password d=System.Configuration .ConfigurationSettings .AppSettings ["pass"];這裡 的AppSettings["pass"] 中的"pass"保持一致。 當然名字是可以隨便起,但必須一致 |
| webasp.net |