Last active
June 10, 2024 13:41
-
-
Save madcodemonkey/17216111f8ffa8d4515455fb90e1b4e9 to your computer and use it in GitHub Desktop.
Generate SSRS report using WCF in .NET Core Application
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using ServiceReference1; | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.ServiceModel; | |
using System.Threading.Tasks; | |
namespace SSRSSimple | |
{ | |
class Program | |
{ | |
const string ReportExecution2005EndPointUrl = "https://YourServer.com/ReportServer/ReportExecution2005.asmx"; | |
const string SsrsServiceAccountActiveDirectoryUserName = "someActiveDirectoryNameWithoutDomain"; | |
const string SsrsServiceAccountActiveDirectoryPassword = "somePassword"; | |
const string SsrsServiceAccountActiveDirectoryDomain = "someDomain"; | |
const string ReportPath = "/ProjectName/Reports/Report_Overview_Basic_Without_Rdl_Extension"; | |
const string ReportWidth = "8.5in"; | |
const string ReportHeight = "11in"; | |
const string ReportFormat = "PDF"; // Other options include WORDOPENXML and EXCELOPENXML | |
const string HistoryId = null; | |
static void Main(string[] args) | |
{ | |
RunReport().Wait(); | |
Console.WriteLine("DONE !"); | |
} | |
private static async Task RunReport() | |
{ | |
ReportExecutionServiceSoapClient rs = CreateClient(); | |
var trustedHeader = new TrustedUserHeader(); | |
LoadReportResponse loadReponse = await LoadReport(rs, trustedHeader); | |
await AddParametersToTheReport(rs, loadReponse.ExecutionHeader, trustedHeader); | |
RenderResponse response = await RenderReportByteArrayAsync(loadReponse.ExecutionHeader, trustedHeader, rs, ReportFormat, ReportWidth, ReportHeight); | |
SaveResultToFile(response.Result, "SomeFileName.pdf"); | |
} | |
private static async Task<LoadReportResponse> LoadReport(ReportExecutionServiceSoapClient rs, TrustedUserHeader trustedHeader) | |
{ | |
// Get the report and set the execution header. | |
// Failure to set the execution header will result in this error: "The session identifier is missing. A session identifier is required for this operation." | |
// See https://social.msdn.microsoft.com/Forums/sqlserver/en-US/17199edb-5c63-4815-8f86-917f09809504/executionheadervalue-missing-from-reportexecutionservicesoapclient | |
LoadReportResponse loadReponse = await rs.LoadReportAsync(trustedHeader, ReportPath, HistoryId); | |
return loadReponse; | |
} | |
private static async Task<SetExecutionParametersResponse> AddParametersToTheReport(ReportExecutionServiceSoapClient rs, ExecutionHeader executionHeader, TrustedUserHeader trustedHeader) | |
{ | |
// Add parameters to the report | |
var reportParameters = new List<ParameterValue>(); | |
reportParameters.Add(new ParameterValue() { Name = "ProjectID", Value = "1434" }); | |
reportParameters.Add(new ParameterValue() { Name = "GeographyID", Value = "6071" }); | |
reportParameters.Add(new ParameterValue() { Name = "Radius", Value = "20" }); | |
reportParameters.Add(new ParameterValue() { Name = "PreparedBy", Value = "Dave" }); | |
reportParameters.Add(new ParameterValue() { Name = "PreparedFor", Value = "Someone special" }); | |
reportParameters.Add(new ParameterValue() { Name = "CurrencyId", Value = "142" }); | |
SetExecutionParametersResponse setParamsResponse = await rs.SetExecutionParametersAsync(executionHeader, trustedHeader, reportParameters.ToArray(), "en-US"); | |
return setParamsResponse; | |
} | |
private static async Task<RenderResponse> RenderReportByteArrayAsync(ExecutionHeader execHeader, TrustedUserHeader trustedHeader, | |
ReportExecutionServiceSoapClient rs, string format, string width, string height) | |
{ | |
string deviceInfo = String.Format("<DeviceInfo><PageHeight>{0}</PageHeight><PageWidth>{1}</PageWidth><PrintDpiX>300</PrintDpiX><PrintDpiY>300</PrintDpiY></DeviceInfo>", height, width); | |
var renderRequest = new RenderRequest(execHeader, trustedHeader, format, deviceInfo); | |
//get report bytes | |
RenderResponse response = await rs.RenderAsync(renderRequest); | |
return response; | |
} | |
private static ReportExecutionServiceSoapClient CreateClient() | |
{ | |
var rsBinding = new BasicHttpBinding(); | |
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; | |
var rsEndpointAddress = new EndpointAddress(ReportExecution2005EndPointUrl); | |
var rsClient = new ReportExecutionServiceSoapClient(rsBinding, rsEndpointAddress); | |
// Set user name and password | |
rsClient.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation; | |
rsClient.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential( | |
SsrsServiceAccountActiveDirectoryUserName, | |
SsrsServiceAccountActiveDirectoryPassword, | |
SsrsServiceAccountActiveDirectoryDomain); | |
return rsClient; | |
} | |
private static void SaveResultToFile(byte[] result, string fileName) | |
{ | |
using (var fs = File.OpenWrite($"c:\\temp\\{fileName}")) | |
using (var sw = new StreamWriter(fs)) | |
{ | |
fs.Write(result); | |
} | |
} | |
} | |
} |
Thank you so much for this! Absolute genius, saved me so much time!!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you so much for this code example together with the helpful advice from @Seany84 about security mode and credential type! I was able to render the PDF and save it successfully :) (using .NET 8 at the moment)