I would like to add a PDF file containing corperate identity information and graphics on every page of a reporting services report. This report is rendered from the report viewer of Dynamics CRM. I was looking into writing a rendering extensions which calls the existing PDF export rendering extension and by using a PDF component like ABCPdf.
I know howto get the PDF background rendering done but I was unable to call the an existing rendering extension from a new implementation.
The existing PDF rendering extension is a sealed class and it appeared to be impossible to use its render method from another implementation.
Then I tried to call the report server directly using a http request and I cannot get this to work because of an impersonation issue. I get the following error message: “No Microsoft Dynamics CRM user exists with the specified domain name and user ID”
I think I am on the right track but I have no idea howto get the security credentials right from the context of an rendering extension.
If I only can get the contents of the pdf as a stream I will be able to add a background to it.
public class PdfWithBackgroundRenderer : IRenderingExtension
{
public void GetRenderingResource(Microsoft.ReportingServices.Interfaces.CreateAndRegisterStream createAndRegisterStreamCallback, System.Collections.Specialized.NameValueCollection deviceInfo)
{
}
public bool Render(Report report, System.Collections.Specialized.NameValueCollection reportServerParameters, System.Collections.Specialized.NameValueCollection deviceInfo, System.Collections.Specialized.NameValueCollection clientCapabilities, ref System.Collections.Hashtable renderProperties, Microsoft.ReportingServices.Interfaces.CreateAndRegisterStream createAndRegisterStream)
{
//http://localhost/Reserved.ReportViewerWebControl.axd?ReportSession=3i414gm5fcpwm355u1ek0e3g&ControlID=417ac5edf4914b7a8e22cf8d4c7a3a8d&Culture=1043&UICulture=1033&ReportStack=1&OpType=Export&FileName=%7bF64F053A-5C28-E011-A676-000C2981D884%7d&ContentDisposition=OnlyHtmlInline&Format=PDF
string Url = "http://localhost/Reserved.ReportViewerWebControl.axd";
Url += "?ExecutionID=" + reportServerParameters["SessionID"];
Url += "&ControlID=" + Guid.Empty;
Url += "&Culture=1043";
Url += "&UICulture=1033";
Url += "&ReportStack=1";
Url += "&OpType=Export";
Url += "&FileName=" + report.Name;
Url += "&ContentDisposition=OnlyHtmlInline";
Url += "&Format=PDF";
Stream outputStream = createAndRegisterStream(report.Name, "pdf", Encoding.UTF8, "application/pdf", true, Microsoft.ReportingServices.Interfaces.StreamOper.CreateAndRegister);
StreamWriter writer = new StreamWriter(outputStream);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
request.Credentials = System.Net.CredentialCache.DefaultCredentials;
request.Timeout = 20000;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
writer.Write(reader.ReadToEnd());
writer.Flush();
return false;
}
public bool RenderStream(string streamName, Report report, System.Collections.Specialized.NameValueCollection reportServerParameters, System.Collections.Specialized.NameValueCollection deviceInfo, System.Collections.Specialized.NameValueCollection clientCapabilities, ref System.Collections.Hashtable renderProperties, Microsoft.ReportingServices.Interfaces.CreateAndRegisterStream createAndRegisterStream)
{
return false;
}
public string LocalizedName
{
get { return "PDF Renderer with background"; }
}
public void SetConfiguration(string configuration)
{
}
}
There is a way, and it takes only a couple of lines.
The idea is to call an existing rendering extension’s render method from a new rendering extension. This will give you the rendering result as a stream which you can modify.
I could not find a solution online but found some forum answers claiming that this could not be accomplished.
The hard part is to get your head around the delegate function that is used. Once you understand what is happening the solution becomes a simple one.
This code is tested with Reporting Services 2008. This method is very useful if you want to modify rendering results created by existing SSRS rendering extsions. You can do string replacements, change the CSV output according to your needs or as in our case sign or update a PDF document.