-
-
Save madcodemonkey/17216111f8ffa8d4515455fb90e1b4e9 to your computer and use it in GitHub Desktop.
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); | |
} | |
} | |
} | |
} |
Thanks so much! Very helpful.
Thank you so much! You saved me now
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
Thanks for the nice demo
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?
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.asmxHello,
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.
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.
This is so helpful. Thank you!
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)
Thank you so much for this! Absolute genius, saved me so much time!!
thank you! I'm a programmer for state government in Alaska, porting these old reports and embedding them would have been an entire pain w/o this gist - so thanks!