Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Using Custom Data Source to create RDLC Reports

0.00/5 (No votes)
7 Nov 2012 9  
Using custom list to create Report and report with Sub Report using RDLC and Report Viewer.

Introduction 

I am working on a project and have the task of evaluating different reporting engines which can be integrated into or are well suited for our project. I came across a freely provided reporting system by Microsoft. Though initially it looks very difficult for me to understand, when I delved further into it I liked it very much.

I searched the internet, relevant forums, and after an intensive study, I am publishing my findings here. This course is good for people who have a basic knowledge of web applications, class libraries and how to use them, and the target audience are beginners in the reporting world.

Course for study 

  1. Creating our Custom Data (Using List) 
  2. Creating a Report using RDLC based on Custom Data
  3. Publishing Report
  4. Creating Secondary Custom Data (Using List)
  5. Creating Sub-Report and attaching to Main Report
  6. Adding Parameter to sub-report and passing data from Main Report
  7. Adding code to handle the Sub-Report
  8. Publish Report Again 

Creating our Custom Data (Using List)  

  1. Create a Web Application by selecting File->New->Project, select ASP.NET Web Application in Visual Studio 2010, and provide the name CpReportCustomData.
  2. Similarly now add a class library which will act as our data source to keep the code simple and separate, say our class library name is CpReportCustomData.Data. Remove the default class1.cs from the project.
  3. Now add a new class Employee in CpReportCustomData.Data, which would look something like this once complete:
  4. public class Employee
    {
        public  int  ID { get; set; }
        public string    Name { get; set; }
        public int  Age { get; set; }
    }

    See I have created a basic class, nothing fancy in it.

  5. Now add our CustomDS class which will act as an intermediary employee list and reports. Our CustomDS class would look something like this:
  6. public class CustomDS
    {
        private static List <employee> _lstEmployee = null;
        public static List <employee> GetAllEmployees()
        {
            if (_lstEmployee == null)
            {
                _lstEmployee = new List <employee> ();
                _lstEmployee.Add( new Employee()
                {
                    ID=1,
                    Name="Alok",
                    Age=30
                });
    
                _lstEmployee.Add(new Employee()
                {
                    ID = 2,
                    Name = "Ashish",
                    Age = 30
                });
    
                _lstEmployee.Add(new Employee()
                {
                    ID = 3,
                    Name = "Jasdeep",
                    Age = 30
                });
    
                _lstEmployee.Add(new Employee()
                {
                    ID = 4,
                    Name = "Kamlesh",
                    Age = 31
                });
            }
            return _lstEmployee;
        }
    }
  7. Compile and Build the class library. 
  8. Add a Reference of your class library in the web-application.

Creating a Report Using RDLC based on Custom Data

  1. Now your data setup is complete. Add a report, right click on the Web Application -> Add New Item -> Reporting -> Reporting Wizard, name it as rptAllEmployees.
  2. You have two options here, either try to build the report yourself or take help of the Report Wizard to create a skeleton based on DS.

  3. Once you add the report, the Dataset properties window would be open, choose Dataset name as DSALLEmployee and select Data Source as cpReportCustomData.Data and select CustomDS(GetAllEmployees) in Available Dataset. Once you have done this setup, the Fields list control would show you all the available Data fields.
  4. Important: The Dataset name is very important, you have to provide this name every time you fill up data into the reports. We will come to this point later.

  5. Now select all the available fields into the report and uncheck both Show Sub Report and Expand Group checkboxes. 
  6. The basic framework would be ready and your report would look something like this:

Publishing Report

  1. Now in the default.aspx file, add Report viewer control from the tool box (name it rptViewer), since Report Viewer also requires ScriptManger, add that too.
  2. Now assign rptViewer our report (rptAllEmployees.rdlc) by selecting it in the smart tag window.
  3. Now click on Choose data source and click on OK on the resultant dialog box. It will automatically add the reference to our DS. If you see the code behind, our Report Viewer HTML tag looks something like this:
  4. <rsweb:ReportViewer ID="rptViewer" runat="server" Width="100%"
           Font-Names="Verdana" Font-Size="8pt" InteractiveDeviceInfos="(Collection)"
           WaitMessageFont-Names="Verdana" WaitMessageFont-Size="14pt">
        <LocalReport ReportPath="rptAllEmployees.rdlc">
            <DataSources>
                <rsweb:ReportDataSource DataSourceId="ObjectDataSource1" Name="DSAllEmployee" />
            </DataSources>
        </LocalReport>
    </rsweb:ReportViewer>
    
    <asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
        SelectMethod="GetAllEmployees" TypeName="CpReportCustomData.Data.CustomDS">
    </asp:ObjectDataSource>
  5. Run and See the report.

Summary till now

  • Created a custom Data class and returned it as a list of class objects using a static function from the class library
  • Created a report using report wizard and selected a class library as Data Source and a static function as dataset
  • Added a Report Viewer control on the Webpage, attached our report to it, and bound it to a dataset to display data

Creating Secondary Custom Data (Using List)

  1. Add a new class EmployeeFamily in the CpReportCustomData.Data class library, which would look something like this once complete. Here you can consider the ID column as foreign key to the employee ‘ID’ field.
  2. public class EmployeeFamily
    {
        public int ID { get; set; }
        public String Name { get; set; }
        public string Relation { get; set; }
    }
  3. Similarly, add get function in the CustomDS class to which will return a list of Employee Families. Once complete, it would look like this:
  4. private static List<EmployeeFamily> _lstEmployeeFamily = null;
    
    public static List<EmployeeFamily> GetAllEmployeeFamily()
    {
        if (_lstEmployeeFamily == null)
        {
            _lstEmployeeFamily = new List<EmployeeFamily>();
            _lstEmployeeFamily.Add(new EmployeeFamily()
            {
                ID = 1,
                Name = "AlokWife",
                Relation = "Wife"
    
            });
    
            _lstEmployeeFamily.Add(new EmployeeFamily()
            {
                ID = 1,
                Name = "AlokDaughter",
                Relation = "Daughter"
    
            });
    
            _lstEmployeeFamily.Add(new EmployeeFamily()
            {
                ID = 2,
                Name = "AshishWife",
                Relation = "Wife"
    
            });
    
            _lstEmployeeFamily.Add(new EmployeeFamily()
            {
                ID = 3,
                Name = "JasdeepFather",
                Relation = "Father"
    
            });
            _lstEmployeeFamily.Add(new EmployeeFamily()
            {
                ID = 3,
                Name = "JasdeepMother",
                Relation = "Mother"
    
            });
    
            _lstEmployeeFamily.Add(new EmployeeFamily()
            {
                ID = 4,
                Name = "KamleshWife",
                Relation = "Wife"
    
            });
    
            _lstEmployeeFamily.Add(new EmployeeFamily()
            {
                ID = 4,
                Name = "KamleshDaughter",
                Relation = "Daughter"
    
            });
        }
        return _lstEmployeeFamily;
    }
  5. Build the class library to update the changes done.

Creating a Sub-Report and attaching to the Main Report

  1. Follow the steps I used to create a report in Creating a Report using RDLC based on Custom Data, and instead of rptAllEmployees, use name rptEmployeeFamily and select the Dataset Name as DSEmployeeFamily, and instead of CustomDS(GetAllEmployees) use CustomDS(GetAllEmployeeFamily).
  2. After all settings, our report looks like this:
  3. Now Navigate to rptAllEmployees, right click on Age field and Insert Row -> Inside Group - Below.
  4. Merge cells of Name and Age columns in newly added row and add subreport from toolbox to it and name it rptEmpFamily. Also for design purposes you can add a text box to the left as Family Details and provide your unique styling to it Smile | <img src=
  5. In rptEmpFamily Properties window, set report name as rptEmployeeFamily, and now our report looks like this:

Adding Parameter to sub-report and passing data from Main Report

  1. Now we have already added our sub report to the main report, and we need to pass information about it to the sub report so we open Report Data view (View->Report Data) of rptEmployeeFamily and right click on parameter to add the id parameter for the report. 
  2. Type name as EmpID, type as Integer, and allow to pass null values to it. 
  3. Now in rptAllEmployees, open sub report properties, navigate to parameters, and add EmpID as Name and [ID] as its value and click OK to save. This step ensures that we are passing ID as parameter to sub report for every iteration of dataset in the main report.
  4. Now your reports are complete, we have to add code in the main report viewer window to handle subrerport processing.

Adding code to handle Sub-Report

  1. Add Sub report processing event handler in page_load (you can add it anywhere, however it should be before you fill data into the report).
  2. if (!Page.IsPostBack)
    {
        rptViewer.LocalReport.SubreportProcessing +=
            new Microsoft.Reporting.WebForms.SubreportProcessingEventHandler(LocalReport_SubreportProcessing);
    }
  3. Now in LocalReport_SubreportProcessing method, add the following code, the code explanation is in comments.
  4. void LocalReport_SubreportProcessing(
        object sender,
        Microsoft.Reporting.WebForms.SubreportProcessingEventArgs e)
    {
        // get empID from the parameters
        int iEmpID = Convert.ToInt32(e.Parameters[0].Values[0]);
    
        // remove all previously attached Datasources, since we want to attach a
        // new one
        e.DataSources.Clear();
    
        // Retrieve employeeFamily list based on EmpID
        var employeeFamily = CpReportCustomData.Data.CustomDS.GetAllEmployeeFamily()
                             .FindAll(element => element.ID == iEmpID);
    
        // add retrieved dataset or you can call it list to data source
        e.DataSources.Add(new Microsoft.Reporting.WebForms.ReportDataSource()
        {
            Name = "DSEmployeeFamily",
            Value = employeeFamily
    
        });
    
    }
  5.  You can see we added the data source with name as DSEmployeeFamily, remember I told you it’s important! Since using it, report recognizes what data to fill.

Publish Report again  

  1. Nothing doing, just sit and relax, Visual Studio 2010 will build and run the report.

Points of Interest 

  1. Report Viewer Control 
  2. Creating RDLC Report 

Special Thanks 

  • My parents, my wife and Parkhi!

History

  • 08-Oct-2012: Started working   
  • 10-Oct-2012: Posted on CodeProject 

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here