Thursday, February 4, 2016

RDLC on WebForm CodeBehind example

Below is a complete source code of a RDLC rendering on aspx webform page.

One important thing to note is that when parameter is used to perform a calculation within the report, the parameter needs to be supplied to the RDLC local report inside ReportViewer. This was a tricky part to understand: I wanted to grab the parameter value from the querystring and feed it directly into a stored procedure in the code-behind, so that I can generate the dataset under the matching "dataset name" embedded in the RDLC report. However, even though the RDLC does not actually use the parameter value to perform query on its own, I still needed to supply the parameter value to the RDLC report separately from feeding it to the stored procedure in the code-behind. Without doing this, the RDLC report would show blank screen.

Another important thing to use is the "SetBasePermissionsForSandboxAppDomain( )" function to allow the local report in ReportViewer to have enough permission so that it is rendered properly.

// RDLC on Webform ("RRA_fax.aspx.cs")
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Security;
using System.Security.Permissions;
using Microsoft.Reporting.WebForms;
using System.Configuration;
using COR.WEB.Helpers;

namespace COR.WEB.Reports
{
    public partial class RRA_fax : System.Web.UI.Page
    {
        int productID;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                initQueryString();
                initReport();
            }
        }

        protected void initQueryString()
        {
            Int32.TryParse(Request.QueryString["ProductID"], out productID);
        }

        protected void initReport()
        {
            string connStr = ConfigurationManager
                .ConnectionStrings["MyConnString"].ConnectionString;
            
            using (SqlConnection conn = new SqlConnection(connStr))
            {
                using (SqlCommand cmd = new SqlCommand("proc_ProductDetails", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    // supplying querystring value as parameter
                    cmd.Parameters.AddWithValue("@productID", productID);

                    using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
                    {
                        DataSet dataSet = new DataSet();
                        adapter.Fill(dataSet);
                        
                        // ds_ProductDetails is the dataset name in RDLC file.
                        ReportDataSource rds1 = 
                            new ReportDataSource("ds_ProductDetails", dataSet.Tables[0]);

                        ReportViewer1.LocalReport.SetBasePermissionsForSandboxAppDomain(
                            new PermissionSet(PermissionState.Unrestricted));
                        ReportViewer1.SizeToReportContent = true;   
                     
                        ReportViewer1.LocalReport.ReportPath = 
                            Server.MapPath("~/RDLC/ProductDetails.rdlc");
                        // important! - if RDLC originally has a parameter, 
                        // we still have to provide a value for it,
                        // even though the RDLC does not actually use it 
                        // to perform a query.
                        ReportParameter param1 = 
                            new ReportParameter("productID", productID.ToString());
                        ReportViewer1.LocalReport.SetParameters(param1);

                        ReportViewer1.LocalReport.DataSources.Clear();
                        ReportViewer1.LocalReport.DataSources.Add(rds1);

                        ReportViewer1.LocalReport.Refresh();
                    }
                }
            }
        }
    }
}

No comments: