Nel precedente articolo sui
SQL Reporting Services abbiamo visto come poter creare a livello di Design i nostri report con questo potente Tool.
In questo articolo vedremo come consumare il
Web Service che viene installato insieme al Database, per la creazione dei Reports.
Il Web Service ci permette di
visualizzare/esportare nei formati più richiesti quali(XML, Excel, PDF, MHTML, HTML,CSV); poter gestire le autorizzazioni, passare parametri(se il report lo richiede) e quindi utilizzare gli stessi strumenti a livello di design anche nel nostro codice.
Vediamo come poter richiamare il Web Service
da una pagina ASP.NET:
Come prima cosa dobbiamo referenziare il Web Service nel solito modo:
La finestra Add Web Reference
L'indirizzo del Web Serivice di solito è il seguente:
http://localhost/reportserver/reportservice.asmx?wsdlChiamiamo la nostra classe Proxy
ReportingServices.
Il metodo esposto che più c?interessa è il
"Render" che restituisce un
Array di bytes che ci servono per poi essere rendirizzati, il metodo accetta questi parametri:
I parametri del metodo RenderReportIl path completo del report cartella + nome report(Es "/Utenti/Cognomi")
Format Il formato in cui si vuole visualizzare/esportare il report e sono consentiti (XML, HTML 4.0,HTML 5.0,Excel, PDF, CSV, Imaggine)
HistoryID Opzionale. L'ID identificativo della storia del report quando viene renderizzato; l'identificativo è basato sulla data di quando viene creato il report
DeviceInfoUna stringa
XML che contiene lo specifico device che viene richiesto per renderizzare l'estensione dello specifico formato.
Parameters Opzionale. Un array di
ParameterValue che rappresentano i parametri del report
CredentialsOpzionale. Un array di
DataSourceCredentials che rappresentano le credenziali per accedere al report se sono attivate le autorizzazioni
ShowHideToggle Opzionale. Mostra o nasconde l'ID
Encoding Output. Restituisce l'enconding utilizzato
MimeType Output. Restituisce il mime-type utilizzato
ParametersUsed Output. Restituisce l'array di ParameterValue che vengono utilizzati nel report
Warnings Output. Restituisce un array di
Warning se ci sono stati degli errori nel reinderizzare il Report
StreamIds Output. Restituisce lo stream, che può essere utilizzato nel metodo
RenderStream per risorse di immagini o file esterni
Vediamo in azione questo metodo:
Supponiamo di volere esportare il Report in
formato Excel e che il report ha bisogno di due parametri che si chiamano:
Descrizione e
Periodo
//Creo la classi Proxy
ReportingService rs= new ReportingService();
//Imposto le credenziali
//se non servono autorizzazioni particolari imposto quelle di base
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
//altrimenti imposto username è password
rs.Credentials = new System.Net.NetworkCredential ("administrator", "password");
//Imposto a null le DataSourceCredentials
DataSourceCredentials[] dsc = null;
//Imposto i parametri
ParameterValue[] parameters = new ParameterValue [2];
parameters[0] = new ParameterValue();
parameters[0].Name = ?Descrizione?;
parameters[0].Value = ?DotnetHell?;
parameters[1] = new ParameterValue();
parameters[1].Name = ?Periodo?;
parameters[1].Value = System.DateTime.Today.ToString(?dd MMMM yyyy?)
//imposto il path del report
string reportPath = ?/Utenti/Cognomi?;
//imposto i parametri di output
ParameterValue[] pv;
Warning[] w;
string outEnconding;
string outMime;
string[] streamIDs = null;
Dopo aver impostato tutti i parametri richiamo il metodo
Render:
byte[] result =
rs.Render(reportPath,
"excel",
null,
"<DeviceInfo><HTMLFragment>false</HTMLFragment><Toolbar>false</Toolbar></DeviceInfo>",
parameters,
dsc,
null,
out outEnconding,
out outMime,
out pv,
out w,
out streamIDs);
Poi andiamo a renderizzare l'Array di Bytes:
//cancello gli Headers e i Content Types
Response.ClearContent();
Response.ClearHeaders();
//se volete solo esportare bisogna utilizzare il comando AppendHeader
Response.AppendHeader("content-disposition",string.Format("Attachment; filename={0}.{1}",nameReport,"xls"));
Altrimenti solo dare il contenttype per il tipo di applicazione
Response.ContentType = "application/vnd.ms-excel";
Infine scriviamo l?arraydi byte, ripuliamo lo stream e chiudiamo
Response.BinaryWrite(result);
Response.Flush();
Response.End();
Attraverso questo Script, cambiando solo il formato possiamo rendere visibile il report in base alle nostre esigenze, questo può essere utilizzato per tutti i formati tranne per il più comune l'HTML.
Questo perché l'HTML è un formato in cui non è tutto salvato in un file e le immagini vengono salvate in file separati e questo non va bene. Come ovviare a questo?
Allora congiuntamente al metodo Render dobbiamo utilizzare il metodo
RenderStream che ritorna una
Stream che serve a recuperare l'immagine nel nostro report.
Per utilizzare questo metodo però dobbiamo inserire il nostro codice nel
Page_Load della pagina
ASP.NET perché viene riscritto il
SessionID nell'Header della pagina e quindi non si deve passare nulla nel
QueryString per non
"sporcare" l'Header.
Il metodo Render deve essere così modificato:
string path = Request.FilePath;
string devInfo = "<DeviceInfo><Toolbar>False</Toolbar><StreamRoot>" +path + "?SessionId={SessionId}&StreamId=</StreamRoot></DeviceInfo>";
result = rs.Render (reportPath,?HTML4.0?, null, devInfo, parameters, dsc, null, out outEnconding, out outMime, out pv, out w, out streamIDs);
e poi scrivere nello stream questo
Response.Clear();
Response.Write(new System.Text.UTF7Encoding().GetString(result).Replace("{SessionId}", rs.SessionHeaderValue.SessionId));
Cosa avviene esattamente?
Con il
DeviceInfo definito in questo modo il ReportingService renderizza le immagini nel SessionID in base al path specificato
(Request.FilePath) , poi tramite il
Response.Write, modifichiamo il SessionID della pagina con il valore del SessionID del Report.
Per questo motivo il codice deve essere inserito nel Page_load, perché inserendo nel SessionID della pagina il SessionID del Report, in automatico le immagini vengono reindirizzate.
Infine dobbiamo utilizzare il
RenderStream per visualizzare le immagini:
//imposto il device info con il formato jpeg
string devImgInfo = "<DeviceInfo><OutputFormat>JPEG</OutputFormat></DeviceInfo>";
//definisco la session per il report
rs.SessionHeaderValue = new SessionHeader();
rs.SessionHeaderValue.SessionId = Request.QueryString["SessionId"];
rs.SessionHeaderValue.IsNewExecution = false;
byte[] buffer = rs.RenderStream(reportPath, "HTML4.0", Request.QueryString["StreamId"], null, devImageInfo, parameters, out outEnconding, out outMime);
//infine scrivo sullo stream della pagina
Response.Clear();
Response.ContentType = "image/JPEG";
Response.BinaryWrite(result);
Se provate ad usare il
Debug vedrete che passerà sull'evento
Load tante volte quante sono le immagini presenti sul report.
Infine se fate tasto destro su una delle immagini create dal report vedrete che il path è simile a questo
http://localhost/viewReport.aspx?SessionId=n5qobb3nanjsxi45zsvnxn45&StreamId=C_ConclusioniCome già detto nel precedente articolo da David, questi
SQL Reporting Services sono una vera bomba e il Web Service che espongono è un'altra dimostrazione della potenza offerta da questo prodotto.