SSRS – Updating Linked Report Page Properties

Page property changes made to Microsoft SQL Server Reporting Services (SSRS) reports are not passed on to linked reports. For example, changing a parent report’s page size from letter to legal will not change child linked reports’ page sizes to legal.

Sometimes, it’s desirable to synchronize child report page settings to their parents. Brian Welcker posted a code sample showing how to automate this property copying using the now old-style .Net 2.0 Web Reference approach. Let’s implement the same functionality using the modern (though, unfortunately, more verbose) Service Reference approach.

For our example, we’ll use C# executed in the context of a Console Application.

Creating the Service Reference

In Solutions Explorer, right-click on the project’s References folder and select Add Service Reference. In the dialog that’s displayed, input your reporting server’s web service URL, then click Go. Once the service information fetching completes, click OK. (If you’d like, adjust the namespace to be used for the service proxy classes before clicking OK.)

Code

using System;
using System.ServiceModel;
using rs = PropertySync.ReportingService;

namespace PropertySync
{
    class Program
    {
        static void Main(string[] args)
        {
            var service = new rs.ReportingService2010SoapClient();

            // Retrieve a list of reports.
            rs.CatalogItem[] reports = null;
            service.ListChildren(new rs.TrustedUserHeader(), "/", true, out reports);

            // List of properties to copy from parent to linked reports.
            var requestedProperties = new rs.Property[] {
                new rs.Property { Name = "PageHeight" },
                new rs.Property { Name = "PageWidth" },
                new rs.Property { Name = "TopMargin" },
                new rs.Property { Name = "BottomMargin" },
                new rs.Property { Name = "LeftMargin" },
                new rs.Property { Name = "RightMargin" }
            };

            foreach (var report in reports) {
                Console.Write("{0} ({1})", report.Name, report.Path);

                if (report.TypeName == "LinkedReport") {
                    string parentReportLink = null;
                    service.GetItemLink(new rs.TrustedUserHeader(), report.Path, out parentReportLink);

                    // Fetch interested property values from parent report.
                    ReportingService.Property[] parentValues = null;
                    service.GetProperties(new rs.ItemNamespaceHeader(), new rs.TrustedUserHeader(), parentReportLink, requestedProperties, out parentValues);

                    // Set the child report's properties to the just-fetched values.
                    service.SetProperties(new rs.TrustedUserHeader(), report.Path, parentValues);
                    Console.WriteLine(" -- properties updated from {0}", parentReportLink);
                } else {
                    Console.WriteLine(" -- non-linked - skipped");
                }
            }
        }
    }
}

Compile and run. If the application executes successfully, we’re done!

Configuring the Binding

If the program fails with a security error (perhaps a MessageSecurityException), you probably need to adjust your web service binding configuration. Your code is probably trying to execute web service methods anonymously (without passing authentication credentials) while SSRS is probably configured to require client authentication.

The exact binding settings required depend on your server’s configuration—detailing the various possibilities is beyond the scope of this article. A common client configuration scenario is illustrated below:

var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

var endpointUri = "http://reporting/ReportServer_SQL/ReportService2010.asmx";
var service = new rs.ReportingService2010SoapClient(binding, new EndpointAddress(endpointUri));
service.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

If you are using integrated (Windows) security, you may need to run your application as an administrator in order for credentials to be passed. (Hint: if you are launching the program from within Microsoft Visual Studio, run Visual Studio as an administrator.)

2 thoughts on “SSRS – Updating Linked Report Page Properties

  1. Michael Finley

    Could you give me instructions on how to implement this script? Is it done for each project/solution in Visual Studio? This appears to be what we may need but I’m unclear how to use it.

    Thanks,

    Reply
    1. Ben Gribaudo Post author

      Hello Michael,

      Sure thing! To implement this solution, first use Microsoft Visual Studio to create a new C# .Net console project. Then, in that solution, replace the contents of Program.cs with the code provided above and add the Service Reference mentioned in this post.

      Hope this helps!

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *