Jul 22

This article describes how to render a list of data sources and dataset's from with a Report Definition (.RDL) file, while using the SQL Server Reporting Services Web Services. You will find a dowload of the code at the end of the article.

This article assumes you have the following:

  • SQL Server 2008 and Reporting Services installed
  • Microsoft Visual Studio 2008 installed
  • Experience with Reporting Services 2005/2008 
  • Experience with ASP.NET and C#
  • Experience with the Reporting Services SOAP API

Steps Taken:

  1. Create ASP.NET Web Application
  2. Reference Reporting Services Web Services SOAP API
  3. Add Web Form
  4. Reference required namespaces  
  5. Create code for both ListReportDataSource and ListReportDataset
  6. Run code 

Create ASP.NET Web Application

1) Open Microsoft Visual Studio 2008 from Start >> All Programs >> Microsoft Visual Studio 2008 >> Microsoft Visual Studio 2008

2) From the menubar, select File >> New >> Project

reporting builder 2.0

3) Expand the C# node and select the Web child node.

4) From the template pane, select ASP.NET Web Application.

5) Name the project "RSIntegrationDemo".

reporting builder 2.0

6) Click OK.

Reference Reporting Services SOAP API

1)  From within your Solution Explorer pane, right click on the project name and select Add Web Reference... to create a new web services reference.

reporting builder 2.0

2) For URL: enter "http://localhost/reportserver/ReportService2005.asmx?wsdl" (replace localhost with your server name, if different).

3) For Web Reference Name: enter RS2005.

reporting builder 2.0

4) Click Add Reference button.

You will notice a new folder named Web References with RS2005 reference located within the folder.

reporting builder 2.0

 You have completed referencing the Reporting Services WSDL

 Add Web Form

1) Create a new Web Form and name it "RSDataset.aspx".

Reference Namespaces

1) Open the RDLUpload.aspx.cs and add the following additional namespaces: 

using System.Web.Services.Protocols; // protocols used to transmit data across the wire using ASP.NET

using RSIntegrationDemo.RS2005; // your wsdl reference

//used for ListReportDataset

using System.Xml;

using System.Xml.XPath;

using System.IO;

Adding the Data Source Code

The ListReportDataSource method will return all data sources within a report, by using the GetItemDataSources method, within the Reporting Services SOAP API. The custom method ListReportDataSource takes one parameter - ReportPath (string).

  /// <summary>

        /// lists all datasources within a report definition (.rdl)

        /// </summary>

        /// <param name="reportName"></param>

        private void ListReportDataSource(string reportPath)

        {

            DataSource[] dataSources = null;

 

            try

            {

                dataSources = rs.GetItemDataSources(reportPath);

 

                if (dataSources != null)

                {

                    foreach (DataSource ds in dataSources)

                    {

                        Response.Write(ds.Name + "<br />");

                    }

                }

            }

            catch (SoapException e)

            {

                Response.Write(e.Detail.InnerXml.ToString());

            }           

        }

Adding the Dataset Source Code

The ListReportDataset method will return all dataset items within a report, by using the GetReportDefinition method, within the Reporting Services SOAP API. In addition to the GetReportDefinition, we use the following objects to help with reading the stream:

  • byte[] - array of bytes 
  • XmlDocument - Represents an XML document
  • MemoryStream - Creates a stream whose backing store is memory. In this case we use for initializing a new non-resizable instance of the MemoryStream class based on the specified byte array.
  • XmlNode - Represents a single node in the XML document. References our XmlDocument object.
  • XmlNodeList - Represents an ordered collection of nodes. All the elements under our Root Node (XmlNode reference and xpath).

The custom method ListReportDataset takes one parameter - ReportPath (string).

        /// <summary>

        /// List all dataset(s) names within a report definition (.rdl) file

        /// </summary>

        /// <param name="reportPath"></param>

        private void ListReportDataset(string reportPath)

        {

            byte[] reportDefinition = null;

            XmlDocument xmldoc = null;

 

            reportDefinition = rs.GetReportDefinition(reportPath);

 

            using (MemoryStream rdlFile = new MemoryStream(reportDefinition))

            {

                xmldoc = new XmlDocument();

                xmldoc.Load(rdlFile);

                rdlFile.Close();

            }

 

            XmlNode root = xmldoc.DocumentElement;

            // Get all the elements under the root node.

            XmlNodeList nodelist = root.SelectNodes("descendant::*");

 

            foreach (XmlNode node in nodelist)

            {

                if (node.Name == "DataSets") // Only search DataSets.

                {  

                    XmlNodeList childList = node.ChildNodes;

 

                    foreach (XmlNode childnode in childList)

                    {

                        if (childnode.Name == "DataSet") // Check if DataSet element exists.

                        {

                            Response.Write(childnode.Attributes["Name"].Value + "<br />");

                        }

                    }

                }

            }

        }

Run Code

1) You'll need to call the methods in your Page_Load before running your code. Enter the following code (change the report path to desired location):

  private ReportingService2005 rs;

 

        protected void Page_Load(object sender, EventArgs e)

        {

            rs = new ReportingService2005();

            // Create an instance of the Web service proxy and set the credentials

            rs.Credentials = System.Net.CredentialCache.DefaultCredentials;

 

            if (!IsPostBack)

            {

                // get list of data sources...

                ListReportDataSource("/Corporate Reports/Company Sales 2008");

                // get list of dataset's...

                ListReportDataset("/Corporate Reports/Company Sales 2008");

            }

        }

That's it! Think about applying these concepts while using custom user controls for best results.

Cheers!

Download the code here: RSIntegrationDemo.zip (442.21 kb)

Jun 24

Reporting Services provides the ability to add references to embededed VB.NET code from within the report. You can use this feature to create reusable functions that are called more than once in a report. This post walks you though the steps needed to add embedded code to your reports.

Note: Custom code can include new custom constants, variables, functions, or subroutines. You can include read-only references to built-in collections such as the Parameters collection. However, you cannot pass sets of report data values to custom functions; specifically, custom aggregates are not supported.   

The article assumes you have the following:

  • Experience in designing reports in Reporting Services
  • Both SQL Server and Reporting Services installed
  • Business Intelligence Development Studio (BIDS)

Adding Embedded Code

1) Open and existing report project from BIDS.

2) From the Solution Explorer, double click on an existing report, or simply create a new one.

3) Select Design tab, and click your mouse anywhere in the design pane.

4) From the Toolbox pane, drag and drop a TextBox object to the report designer.

reporting builder 2.0

5) From the top menu bar select Report >> Report Properties

Note: if you don't see the Report menu item, try clicking your mouse anywhere in the design view; you should then see the menu item.

reporting builder 2.0

6) The Report Properties window opens. From within the left pane, select Code.

7) Enter the following VB.NET code in the Custom Code field.

Public Function Sec(ByVal angle As Double) As Double
    ' Calculate the secant of angle, in radians.
    Return 1.0 / Math.Cos(angle)
End Function

Public Function Sinh(ByVal angle As Double) As Double
    ' Calculate hyperbolic sine of an angle, in radians.
    Return (Math.Exp(angle) - Math.Exp(-angle)) / 2.0
End Function

Public Function GetPi() As Double
    ' Calculate the value of pi.
    Return 4.0 * Math.Atan(1.0)
End Function

reporting builder 2.0

8) Click OK to save and close the Report Properties window.

9) Right click on the Text Box you added previously and select Expression...

reporting builder 2.0

10) Enter the following code in the text box:

=Code.GetPi()

reporting builder 2.0

11) Click OK to save and close the Expression window.

12) Click the Preview tab to run the report. You should see a similar result.

reporting builder 2.0

That is it! Try calling the remaining functions to test your code.

Cheers!

function reference: http://msdn.microsoft.com/en-us/library/thc0a116(VS.80).aspx