Generare un report SSRS in .NET Core
Un esempio di come generare un report di SQL Server Reporting Services (SSRS) in PDF usando C# con .NET Core.
Si parte aggiungendo un servizio WCF in Visual Studio
che punta all'endpoint di SSRS /reportserver/ReportExecution2005.asmx
Aggiunta la referenza (namespace WSReport) si può creare il metodo che restituisce il client (ReportExecutionServiceSoapClient)
e il metodo che genererà il report nel formato scelto
serve anche una piccola classe di supporto FileBytes
A questo punto posso richiamare la generazione del report
Si parte aggiungendo un servizio WCF in Visual Studio
che punta all'endpoint di SSRS /reportserver/ReportExecution2005.asmx
Text
https://nomeServerReporting/reportserver/ReportExecution2005.asmx
Vedi anche Report Server Web Service Endpoints
Aggiunta la referenza (namespace WSReport) si può creare il metodo che restituisce il client (ReportExecutionServiceSoapClient)
C#
using System.Threading.Tasks;
using WSReport;
// default server
string REPORTING_URL = "https://nomeServerReporting";
private ReportExecutionServiceSoapClient CreateClient(string serverUrl = null)
{
if (serverUrl == null) {
serverUrl = REPORTING_URL;
}
var rsBinding = new BasicHttpBinding();
if (serverUrl.StartsWith("https:", StringComparison.InvariantCultureIgnoreCase))
{
rsBinding.Security.Mode = BasicHttpSecurityMode.Transport;
}
rsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
// So we can download reports bigger than 64 KBytes
// See https://stackoverflow.com/questions/884235/wcf-how-to-increase-message-size-quota
rsBinding.MaxBufferPoolSize = 20000000;
rsBinding.MaxBufferSize = 20000000;
rsBinding.MaxReceivedMessageSize = 20000000;
// url del sirvizio di reporting
string url = serverUrl.TrimEnd('/') + "/ReportServer/ReportExecution2005.asmx";
var rsEndpointAddress = new EndpointAddress(url);
var rsClient = new ReportExecutionServiceSoapClient(rsBinding, rsEndpointAddress);
// imponsto l'autenticazione integrata con l'utente corrente
rsClient.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
rsClient.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
return rsClient;
}
C#
private async Task<FileBytes> GenerateReport(string reportPath, string reportFormat)
{
// creo il client usando la url del server di default
ReportExecutionServiceSoapClient rs = CreateClient();
var trustedHeader = new TrustedUserHeader();
// imposto il path e carico il report
LoadReportResponse loadReponse = await rs.LoadReportAsync(trustedHeader, reportPath, null);
// aggiungo i parametri (DateFrom e StatusIDs) al report
var reportParameters = new List<ParameterValue>();
reportParameters.Add(new ParameterValue() { Name = "DateFrom", Value = DateTime.Today.AddDays(-2).ToString("yyyy-MM-dd") });
reportParameters.Add(new ParameterValue() { Name = "StatusIDs", Value = "0,10,50,100" });
// imposto nel report i parametri e la lingua (it-IT)
await rs.SetExecutionParametersAsync(loadReponse.ExecutionHeader, trustedHeader, reportParameters.ToArray(), "it-IT");
// imposto le dimensioni del foglio per il render in PDF (foglio A4)
string width = "21cm";
string height = "29.7cm";
string deviceInfo = $"<DeviceInfo><PageHeight>{width}</PageHeight><PageWidth>{height}</PageWidth><PrintDpiX>300</PrintDpiX><PrintDpiY>300</PrintDpiY></DeviceInfo>";
var renderRequest = new RenderRequest(loadReponse.ExecutionHeader, trustedHeader, reportFormat, deviceInfo);
// mi faccio ritornare i bytes che rappresentano il report nel formato richiesto
RenderResponse response = await rs.RenderAsync(renderRequest);
// determino l'estensione in base al tipo di formato
string extension = "txt";
if (reportFormat.Equals("PDF"))
{
extension = "pdf";
}
else if (reportFormat.Equals("EXCELOPENXML"))
{
extension = "xlsx";
}
else if (reportFormat.Equals("WORDOPENXML"))
{
extension = "docx";
}
string fileName = $"AccountManagement_{DateTime.Today:yyyy-MM-dd}.{extension}";
return new FileBytes
{
FileName = fileName,
Content = response.Result
};
}
C#
public class FileBytes
{
public string FileName { get; set; }
public byte[] Content { get; set; }
}
A questo punto posso richiamare la generazione del report
C#
// url completa del report http://nomeServerReporting/reports/report/Testing/Report1
string reportRelativeUrl = "/Testing/Report1";
string reportFormat = "PDF"; // oppure EXCELOPENXML o WORDOPENXML
// genero il report
var report = await GenearteReport(reportRelativeUrl , reportFormat);
// lo salvo
System.IO.File.WriteAllBytes($@"c:\tmp\{report.FileName}", report.Content);
Oltre al formato PDF si può ottenere anche il formato excel con la chiave EXCELOPENXML.
Per un elenco completo dei comandi supportati vedi URL access parameter reference
Per un elenco completo dei comandi supportati vedi URL access parameter reference
Nel path del report non includere la parte iniziale /reports e sostituire eventuali escape dei caratteri come il %20 con il corrispondente carattere spazio (vedi Url Encode e Decode).