Force SSRS 2008 to use SSRS 2005 CSV rendering

半世苍凉 提交于 2019-11-29 11:40:38

Your question triggered me to finally go out and try to write a custom RenderingExtension. The answer here would be to create an extension that "wraps" the old SSRS 2005 CSV rendering extension and makes it available under a new name in SSRS 2008.

I certainly think it's possible to do this. Unfortunately, I don't have the 2005 SSRS DLL's, so I did my proof of concept by creating an extension that wraps the 2008 CSV renderer. After quite a struggle I finally got this to work. Maybe this answer will help you in implementing this analogously for the 2005 CSV renderer.

A few notes up front:

  • All kudo's should go to "Broes", who wrote an excellent tutorial on his blog for a similar case on PDF watermarks (part 1, part 2), which was invaluable in creating the extension.
  • Microsoft warns about writing an extension that "Writing a custom rendering extension is difficult", and even though they're talking about an extension that actually does something (besides wrapping a default extension), I found just getting the thing to work can be quite a pain as well.

So here are the basic steps:

  1. Create a new class library (.NET 3.5, not 4.0+) with a new class (see code below).
  2. Add a reference to:
    1. Microsoft.ReportingServices.DataRendering (for the default CSV renderer)
    2. Microsoft.ReportingServices.Interfaces
    3. Microsoft.ReportingServices.ProcessingCore
  3. Create a private instance of the CsvReport renderer, initialize it in the constructor.
  4. Implement the IRenderingExtension interface in your class. Route all method calls to the private instance of the wrapped renderer.
  5. Edit the properties of the project to sign it with a strong name.
  6. Compile.
  7. Copy the DLL to the ReportServer bin.
  8. Edit the rssrvpolicy.config file to include your assembly in a CodeGroup element.
  9. Edit the rsreportserver.config file to include the extension.
  10. Reboot the SSRS service.
  11. (Optional) Pray, or light a candle.
  12. Open a report in the report manager, and verify that your extension is there:

Here's the code listing for the class that wraps the default CSV renderer:

using Microsoft.ReportingServices.Interfaces;
using Microsoft.ReportingServices.OnDemandReportRendering;

namespace Ssrs2005CsvRenderingExtension
{
    public class Csv2005Renderer : IRenderingExtension
    {
        private IRenderingExtension oldskoolCsvRenderer;

        public Csv2005Renderer()
        {
            oldskoolCsvRenderer = new Microsoft.ReportingServices.Rendering.DataRenderer.CsvReport();
        }

        public void GetRenderingResource(CreateAndRegisterStream createAndRegisterStreamCallback, 
                                         System.Collections.Specialized.NameValueCollection deviceInfo)
        {
            oldskoolCsvRenderer.GetRenderingResource(createAndRegisterStreamCallback, deviceInfo);
        }

        public bool Render(Microsoft.ReportingServices.OnDemandReportRendering.Report report,
                           System.Collections.Specialized.NameValueCollection reportServerParameters, 
                           System.Collections.Specialized.NameValueCollection deviceInfo, 
                           System.Collections.Specialized.NameValueCollection clientCapabilities,
                           ref System.Collections.Hashtable renderProperties, 
                           CreateAndRegisterStream createAndRegisterStream)
        {
            return oldskoolCsvRenderer.Render(report, 
                                              reportServerParameters, 
                                              deviceInfo, 
                                              clientCapabilities, 
                                              ref renderProperties, 
                                              createAndRegisterStream);
        }

        public bool RenderStream(string streamName, 
                                 Microsoft.ReportingServices.OnDemandReportRendering.Report report, 
                                 System.Collections.Specialized.NameValueCollection reportServerParameters, 
                                 System.Collections.Specialized.NameValueCollection deviceInfo, 
                                 System.Collections.Specialized.NameValueCollection clientCapabilities, 
                                 ref System.Collections.Hashtable renderProperties, 
                                 CreateAndRegisterStream createAndRegisterStream)
        {
            return oldskoolCsvRenderer.RenderStream(streamName,
                                                    report,
                                                    reportServerParameters,
                                                    deviceInfo,
                                                    clientCapabilities,
                                                    ref renderProperties,
                                                    createAndRegisterStream);
        }

        public string LocalizedName
        {
            get { return "Oldskool CSV renderer"; }
        }

        public void SetConfiguration(string configuration)
        {
            oldskoolCsvRenderer.SetConfiguration(configuration);
        }
    }
}

This is the extension as added to the rsreportserver.config:

<Extension Name="OLDSKOOLCSV" Type="Ssrs2005CsvRenderingExtension.Csv2005Renderer,Ssrs2005CsvRenderingExtension"/>

And this is the configuration xml for rssrvpolicy.config as I used it:

<CodeGroup
        class="UnionCodeGroup"
        version="1"
        PermissionSetName="FullTrust"
        Name="OldskoolCsvGroup"
        Description="Code group for oldskool csv extension">
    <IMembershipCondition 
            class="UrlMembershipCondition"
            version="1"
            Url="C:\Program Files\Microsoft SQL Server\MSRS10.SQLSERVER\Reporting Services\ReportServer\bin\Ssrs2005CsvRenderingExtension.dll"
    />
</CodeGroup>

One script that was very useful for quick testing if things worked (mainly because it involved a lot of trial and error), which I execute with the RS Utility:

Public Sub Main()
    Dim items() As Extension
    items = rs.ListExtensions(1)

    For Each item As Extension In items
        Console.WriteLine(item.Name)
    Next item
End Sub 

And that's it. At least it's all the important stuff I can still remember after a few hours of trial and error. To finish with one final note:

  • The Application Event Log sometimes contains SSRS errors. One of them was "SSRS cannot load the ... extension". This was the last hurdle I cleared, and I cleared it by changing the target framework from .NET 4.0 down to 3.5.

Should anyone attempt this with the actual 2005 CSV rendering DLL: let us know whether it was succesful with a comment or an edit to the answer.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!