Skip to content

Instantly share code, notes, and snippets.

@madcodemonkey
Last active June 10, 2024 13:41
Show Gist options
  • Save madcodemonkey/17216111f8ffa8d4515455fb90e1b4e9 to your computer and use it in GitHub Desktop.
Save madcodemonkey/17216111f8ffa8d4515455fb90e1b4e9 to your computer and use it in GitHub Desktop.
Generate SSRS report using WCF in .NET Core Application
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);
}
}
}
}
@sal-420
Copy link

sal-420 commented Oct 12, 2022

Hi
I'm unable to run a successful test
Any assistance with the below 2 errors is appreciated
TEST 1) The app stops on statement 'LoadReportResponse loadReponse = await rs.LoadReportAsync(trustedHeader...' with no error Try/Catch does not catch the error.

TEST 2) Change 'rsBinding.Security.Mode = BasicHttpSecurityMode.Transport;' to 'BasicHttpSecurityMode.TransportCredentialOnly;;'
thows: The provided URI scheme 'https' is invalid; expected 'http'. (Parameter 'via')

changing Https to http thows: The provided URI scheme 'http' is invalid; expected 'https'. (Parameter 'via')

Test Environment
C# console app
.net 5.0
VS2019
IIS
SSRS server
https://xxxxxx.xxxx./reportserver/ReportExecution2005.asmx

@jambutler
Copy link

Thanks for the nice demo

@MCosta88
Copy link

MCosta88 commented Jan 8, 2023

Hi I'm unable to run a successful test Any assistance with the below 2 errors is appreciated TEST 1) The app stops on statement 'LoadReportResponse loadReponse = await rs.LoadReportAsync(trustedHeader...' with no error Try/Catch does not catch the error.

TEST 2) Change 'rsBinding.Security.Mode = BasicHttpSecurityMode.Transport;' to 'BasicHttpSecurityMode.TransportCredentialOnly;;' thows: The provided URI scheme 'https' is invalid; expected 'http'. (Parameter 'via')

changing Https to http thows: The provided URI scheme 'http' is invalid; expected 'https'. (Parameter 'via')

Test Environment C# console app .net 5.0 VS2019 IIS SSRS server https://xxxxxx.xxxx./reportserver/ReportExecution2005.asmx

Hello,

I have the same problem, did you manage to resolve this issue?

@Seany84
Copy link

Seany84 commented Jun 1, 2023

Hi I'm unable to run a successful test Any assistance with the below 2 errors is appreciated TEST 1) The app stops on statement 'LoadReportResponse loadReponse = await rs.LoadReportAsync(trustedHeader...' with no error Try/Catch does not catch the error.
TEST 2) Change 'rsBinding.Security.Mode = BasicHttpSecurityMode.Transport;' to 'BasicHttpSecurityMode.TransportCredentialOnly;;' thows: The provided URI scheme 'https' is invalid; expected 'http'. (Parameter 'via')
changing Https to http thows: The provided URI scheme 'http' is invalid; expected 'https'. (Parameter 'via')
Test Environment C# console app .net 5.0 VS2019 IIS SSRS server https://xxxxxx.xxxx./reportserver/ReportExecution2005.asmx

Hello,

I have the same problem, did you manage to resolve this issue?

Changing lines 86 & 87 from this:

rsBinding.Security.Mode = BasicHttpSecurityMode.Transport;
rsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

to this:

rsBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
rsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;

This change made it possible for me to connect to the SSRS ASMX web service over HTTP while using Windows Auth to connect.

@karthit
Copy link

karthit commented Nov 28, 2023

Thanks for this nice example, how can i set the timeout property for this particular report execution alone?
Note: i've tried using timeout property on Soap client, which is timeout the current request alone, but the ssrs report which is triggered in ssrs is still active ( ssrs not honoring the timeout setting).
Any help on this would be appreciated.

@sam-wheat
Copy link

This is so helpful. Thank you!

@shimano-zd
Copy link

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)

@CupraAli
Copy link

CupraAli commented Jun 10, 2024

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