Thursday, January 7, 2010

Using RDLC files and Microsoft Report Viewer in ASP.NET

Great way to display data is using Microsoft Report Viewer on ASP.NET pages. However you don't want to create a new page for each report you generate. I came across this problem recently and decided that the best way for me would be to create just one page with a report viewer where I could display all my reports.

Now I'm going to show you how i did it...

Step 1

Under root folder I've created "Reports" folder. This is were I'm going to store all my reports (rdlc files) and a default page to display them.

Step 2

Create default.aspx under ~\Reports and place a MicrosoftReportViewer on it.

Step 3

Create new dataset "ReportsDataSet.xsd" under ~\App_Code. Here we are going to define the dataset classes.

The first datatable we need is for some general report parameters we would like to display on the report. So create a new datatable and add some columns to it. I've created a datatable called "Reports" with 3 columns - ReportName, ReportDate and Parameter1. I also addes some tables from Northwind database. Just drag and drop from server explorer.

Now it should look like this.

Step 4

Create a new report under ~\Reports lets call it "CustomersReport.rdlc"

Goto Report - Data Sources and add ReportDataSet_Reports and ReportDataSet_Customers to your report sow we can use them.

Step 5

Design your report using selected datasources.

Step 6

Open ~\Reports\default.aspx.cs and enter the following code.

This is a method which loads "CustomersReport" in here you can load all the reports you wish.

private void ShowReport(string Report_Name, string Parameter1)
        //path for your reports
        string path = HttpContext.Current.Server.MapPath("~/Reports/");

        ReportViewer1.Reset(); //important
        ReportViewer1.ProcessingMode = Microsoft.Reporting.WebForms.ProcessingMode.Local;
        Microsoft.Reporting.WebForms.LocalReport r = ReportViewer1.LocalReport;
        r.ReportPath = path + Report_Name + ".rdlc";
        Microsoft.Reporting.WebForms.ReportDataSource rds;

        // fill data parameters table so we can use it on reports
        DataTable dtReports = new ReportsDataSet.ReportsDataTable();
        DataRow drReports = dtReports.NewRow();
        drReports["ReportName"] = Report_Name;
        drReports["ReportDate"] = DateTime.Now;
        drReports["Parameter1"] = Parameter1;

        // add parameters table to report data source
        rds = new Microsoft.Reporting.WebForms.ReportDataSource();
        rds.Name = "ReportsDataSet_Reports";
        rds.Value = dtReports;

        if (Report_Name == "CustomersReport")
            ReportsDataSet.CustomersDataTable dtCustomers = new ReportsDataSet.CustomersDataTable();
            ReportsDataSetTableAdapters.CustomersTableAdapter ad = new ReportsDataSetTableAdapters.CustomersTableAdapter();

            rds = new Microsoft.Reporting.WebForms.ReportDataSource();
            rds.Name = "ReportsDataSet_Customers";
            rds.Value = dtCustomers;

Now you can call this method within the ~\Reports\default.aspx page or you can call from other pages passing parameters. For that you will need this extra code.
protected void Page_Load(object sender, EventArgs e)
        if (!IsPostBack)
            string reportName = null;
            string parameter1 = null;

            if (this.Request.QueryString["ReportName"] != null)
                reportName = this.Request.QueryString["ReportName"];

            if (this.Request.QueryString["Parameter1"] != null)
                reportName = this.Request.QueryString["Parameter1"];

            if (reportName != null)
                ShowReport(reportName, parameter1);

I'm just going to put a link on the home page to test that all works fine.
<a href="Reports/Default.aspx?ReportName=CustomersReport">Customers Report</a>

Here is the result.