Upload SSRS report to all subfolders

by Ewald Hofman 16. June 2009 00:50

When you develop a new report for TFS and you want to deploy the report to all team projects, you have to do a lot of work to upload the file and to set the datasources.

This post uses TFS 2008 and SQL Server 2005

There is an easy way to automate that.

1. Add the web service to Reporting Service

Add a new web reference to the project. The url of the web service is http://<servername>/ReportServer/ReportService2005.asmx?wsdl

2. Add the library to upload the file

using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Xml;
using UploadLibrary.ReportService2005;
namespace UploadLibrary
{
    public class Report
    {
        public Report(string[] localFiles)
        {
            LocalFiles = localFiles;
        }
        public string[] LocalFiles { get; set; }
        public void Upload()
        {
            foreach (var subFolder in SubFolders())
            {
                foreach (var localFile in LocalFiles)
                {
                    Upload(subFolder, localFile);
                }
            }
        }
        private void Upload(string subFolder, string file)
        {
            var fi = new FileInfo(file);
            string reportName = fi.Name.Substring(0, fi.Name.Length - fi.Extension.Length);
            string reportPath = "/" + subFolder + "/" + reportName;
            var rs = new ReportingService2005 { Credentials = CredentialCache.DefaultCredentials };
            //Read the file from the file system
            FileStream stream = File.OpenRead(file);
            var bytes = new byte[stream.Length];
            stream.Read(bytes, 0, (int)stream.Length);
            stream.Close();
            //Search for an exiting item in the subfolders (recursively)
            CatalogItem[] items = rs.FindItems("/" + subFolder,
            BooleanOperatorEnum.And,
            new[]
{
new SearchCondition
{
Name = "Name",
Condition = ConditionEnum.Equals,
Value = reportName
}
});
            // Only add the report in the current subfolder
            if (items.Count(c => c.Path == reportPath) > 0)
            {
                //Report exists -> update the report
                rs.SetReportDefinition(reportPath, bytes);
            }
            else
            {
                //Report does not exist -> create a new report
                rs.CreateReport(reportName, "/" + subFolder, false, bytes, new Property[0]);
            }
            //Relocate the datasources to the parent folder
            rs.SetItemDataSources(reportPath, UsedDatasources(file));
        }
        private static string[] SubFolders()
        {
            var rs = new ReportingService2005 { Credentials = CredentialCache.DefaultCredentials };
            var items = rs.ListChildren("/", false);
            return items.Where(i => i.Type == ItemTypeEnum.Folder).Select(i => i.Name).ToArray();
        }
        /// <summary>
        /// Returns an array of all datasources that are in use by the report.
        /// </summary>
        private DataSource[] UsedDatasources(string file)
        {
            var datasources = new Collection<DataSource>();
            // Read the rdl file
            var doc = new XmlDocument();
            doc.Load(file);
            var nsmgr = new XmlNamespaceManager(doc.NameTable);
            nsmgr.AddNamespace("rdl", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
            // Go to the datasources node in the rdl file
            var nodes = doc.SelectNodes("rdl:Report/rdl:DataSources/rdl:DataSource", nsmgr);
            if (nodes != null)
            {
                // Iterate through the datasources in the rdl file
                foreach (XmlNode node in nodes)
                {
                    // Read the name of the datasource
                    var datasourceName = node.Attributes["Name"].InnerText;
                    // Add it to the result
                    datasources.Add(new DataSource
                    {
                        Item = new DataSourceReference { Reference = "/" + datasourceName },
                        Name = datasourceName
                    });
                }
            }
            // Return the result
            return datasources.ToArray();
        }
    }
}

3. Add any UI you like

You can add a winform project to your solution. On the form add a button called uploadReport and a textbox called fileName

private void uploadReport_Click(object sender, EventArgs e)
{
    Cursor = Cursors.WaitCursor;
    try
    {
        //Validation
        if (!File.Exists(fileName.Text))
        {
            MessageBox.Show(this, "Invalid filename", "Validation", MessageBoxButtons.OK,
            MessageBoxIcon.Error);
            return;
        }
        //Start upload
        var rpt = new Report(new string[] { fileName.Text });
        rpt.Upload();
        //Successful upload.
        MessageBox.Show(this, "The report is uploaded to all folders on the server!", "Successful", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    catch (Exception ex)
    {
        MessageBox.Show(this, ex.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    finally
    {
        Cursor = Cursors.Default;
    }
}

Tags:

Reporting

Comments are closed

Powered by BlogEngine.NET 1.6.1.0
Theme by Mads Kristensen


ClusterMap

Widget Statistics not found.

There is an error in XML document (0, 0).X

Recent comments

Comment RSS