2010年12月16日 星期四

透過 Proxy 產生 Reporting Service 2008R2 報表

透過 proxy 呼叫 Reporting Service 所提供的 Web Service,可以提供我們更有彈性的報表管理。在 Reporting Service 2000 時,如果要產生 pdf 報表,使用 http://Repsdev/ReportServer/ReportService.asmx 的 Render( ) 方法來產生報表(Repsdev 是伺服器名稱)。隨著物換星移,當初的 Reporting Service 2000 現今也已換成 Reporting Service 2008R2 了,伴隨著微軟打著無痛升級、效率更好、功能更強的口號,系統也一一升級了,直到... user 打電話通知,報表不能 Run 之後,才發現事情並不是我想的這麼簡單。


版本升級對目前的設計所造成的衝擊,有以下幾點:

1.原先使用的 WebService http://Repsdev/ReportServer/ReportService.asmx ,現在已經不能用了,取而代之的,是可以選擇使用 http://Repsdev/ReportServer/ReportService2005.asmx 或 http://Repsdev/ReportServer/ReportService2010.asmx。確切來說,要知道你的主機上可以使用哪些 WebService,主要是看主機上安裝了哪些版本的 SQL Server。將各個版本的 Reporting Service 列出來比較,就能明瞭了。

SQL Server 2000 Reporting Server >>ReportService.asmx
SQL Server 2005 Reporting Server >>ReportService2005.asmx
SQL Server 2008 Reporting Server >>ReportService2006.asmx
SQL Server 2008R2 Reporting Server >>ReportService2010.asmx

目前我可以使用 ReportService2005.asmx 與 ReportService2010.asmx,是因為主機上裝了 SQL 2005 與 SQL 2008R2,由此解釋,應該可以通吧!


2. Render( ) 方法的入口點,已由 ReportService.asmx 改為 ReportExecutionService2005.asmx,這改變真的也讓人理不出個所以然來。只能靠網友間口耳相傳才會知道,自己則是在 Rendering a report using web services with 2008 R2 (ReportService2010) 這篇文章找到原因的。

3. Render( ) 引數的改變。 Render( ) 所接受的引數,在 ReportExecutionService2005.asmx 是跟 ReportService.asmx 不一樣的。新的 Render( ) 內容,可以參考 ReportExecutionService.Render Method

折騰一陣子後,終於把透過 Proxy 來產生 Reporting Service 報表的問題解決了。最後將完整的測試程式整理於後,以便有興趣的朋友或未來的自己參考參考。

範例是用 VS2003 所撰寫,所以有點懷舊的味道...只差程式沒辦法強調是黑白的而已。


using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.IO;
using System.Configuration;

namespace WebApplication1
{
 /// <summary>
 /// Summary description for WebForm1.
 /// </summary>
 public class WebForm1 : System.Web.UI.Page
 {
  protected System.Web.UI.WebControls.Button btnPDF;
 
  private void Page_Load(object sender, System.EventArgs e)
  {
   // Put user code to initialize the page here
  }

 

  private void btnPDF_Click(object sender, System.EventArgs e)
  {
   MakePDF();
  }

  private void MakePDF()
  {
   //PDF 暫存檔路徑(必須已經存在的檔案路徑)
   string filepath = "D:\\upload\\engage_upd\\PDF\\";
   string filename = filepath+"Quote.PDF";


   //取得 WebService 服務(SQL 2008R2 的 webservice 要使用 ReportExecution2005.asmx )   
   string strRSTmp="http://Repsdev/ReportServer/ReportExecution2005.asmx";   

   
   repsdev.ReportExecutionService rs=new WebApplication1.repsdev.ReportExecutionService();

   //設定 windows 帳號認證(正式使用時,採用此行)   
   //rs.Credentials=System.Net.CredentialCache.DefaultCredentials;

   //測試資料【連接Reporting Server】(測試時,採用此行,固定測試帳號)
   rs.Credentials=new System.Net.NetworkCredential("52xxxx","passwd","network");


   //重新指派 WebService 服務位址
   rs.Url=strRSTmp;
   
   Byte [] result=null;

   //參數收集(呼叫報表時必須傳入的參數,目前範例要傳入 seqsn,ver,isdraft 三個參數)
   repsdev.ParameterValue [] parameter=new WebApplication1.repsdev.ParameterValue[3] ;
   parameter[0]=new WebApplication1.repsdev.ParameterValue();
   parameter[0].Name="seqsn";
   parameter[0].Value="545";
   parameter[1]=new WebApplication1.repsdev.ParameterValue();
   parameter[1].Name="ver";
   parameter[1].Value="";
   parameter[2] = new WebApplication1.repsdev.ParameterValue();
   parameter[2].Name="isdraft";
   parameter[2].Value="1";


   repsdev.ExecutionInfo execInfo=new WebApplication1.repsdev.ExecutionInfo();
   repsdev.ExecutionHeader execHeader=new WebApplication1.repsdev.ExecutionHeader();

   //報表位置
   string reportPath = "/EPath/rptTest";
   string historyID = null;

   rs.ExecutionHeaderValue = execHeader;
   execInfo = rs.LoadReport(reportPath, historyID);
   rs.SetExecutionParameters(parameter, "en-us");


   string mimeType;   
   repsdev.Warning [] warnings=null;
   string [] streamIDs=null;
   string devInfo=@"<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";
   string extension;
   string encoding;
   try
   {
    result=rs.Render("PDF",devInfo,out extension,out mimeType,out encoding,out warnings,out streamIDs);
   }
   catch(Exception e)
   {
    if(e.Message.IndexOf("401")>-1)
    {
     //HTTP 401:沒通過授權
     String scriptString = @"
<script language=JavaScript>
<!-- begin 
alert('您必須登入網域,才能有權限讀取本報表!') ;
//end -->
</script> 
";
     this.RegisterStartupScript("AccessDeny",scriptString);

     return;
    }
    else
     return;
   }

   FileStream fs=new FileStream(filename,FileMode.Create);
   fs.Write(result,0,result.Length);
   fs.Close();
   rs.Dispose();       
  }


 }
}



參考:

01.ReportExecutionService.Render Method

02.What is reportexecution2005.asmx i used this as webreference

03.Rendering a report using web services with 2008 R2 (ReportService2010)

04.SSRS 2008, C# and ReportingService.Render()

05.SSRS 亂七八糟的SOAP API 配對

沒有留言:

張貼留言