Click here to Skip to main content
Click here to Skip to main content

Prototype MVC4 Razor ReportViewer? RDLC

, 20 Jun 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
The intent is to try getting reportviewer like control in MVC razor by rendering RDLC report in View form. Moreover also tried to output report based on search filter criteria in MVC Razor.


Table of Contents
  1. Overview
  2. Requirement Specifications/Prerequisites
  3. Design Specification
  4. Create RDLC Report Design
  5. Model View Controller
  6. Improvement Areas
  7. References

1. Overview

The intent of this article is to help fellow MVC developer to solve the problem related to Reportviewer in MVC Razor framework. To be candid, its an attempt! I searched online to have ways/approach to incorporate Reportviewer in MVC Razor , but all search ends up stating-' no alternative'. I came up with small prototype wherein we can create and build search based report similar to somewhat ReportViewer component.



 



2. Problem Statement /Prerequisites

We require simple filter based report build in MVC Razor. There will be input search filter criteria to display reports in tabular format.


To built solution, we used VS2012 and MVC4 Razor Architecture.


3. Design Specifications

  1. Design RDLC Report .
  2. Create Domain-Model **SearchParameterModel and ***WorldReportModel. SearchParameterModel is class object to store report filter criteria as entered by user. This search parameter then passed to controller on HTTPost triggered by button click event. WorldModel is used to store records from data source.
  3. Create View ReportViewer.chtml.
  4. Create Controller ReportViewerController
  5.  
    What we get?


  1. With this solution we can have flexibility of using stored procedure output(Bind RDLC with datasource of RDLC) with required inputs from MVC razor view.
  2. With this solution we can download report in pDF, word or excel
  3. With this solution we can make use ofimg src="@Url.Action("GenerateAndDisplayReport", "Report", new { territory = Model.Territory, format = Model.Format })" to render report in web

 



4. Create RDLC Report Design

1. Add new item report- Report1.RDLC in the solution.



2. Add new item-dataset -Dataset1.xsd. Manually add column in the datatable using designer view. The column name should match with the public property in Models-ReportModels(Class SearchParameterModel).Any deviation results in error.



When above steps are completed...Check below







3. Click on RDLC file drag and drop required Tablix control and populate with required data set fields. In order to do this, click on Menu-View-Reportdata. Add manually New Dataset , this form will provide you the option to select the dataset1 that we created initially.



For more help. Refer my article.Design Report data Structure in RDLC



 

Fig1. Create dataaset1 schema for RDLC report datasource mapping.



Fig 2. We can reference this dataset1 in Report data as shown in sanpshot below. Right click and add new dataset.





5. Model View Controller

Model: ReportModels

The SearchParameterModel object act as placeholder to accept input parameter to filter report result set. Also below class helps in displaying content of labels as well as used validating input fields. The format property is used to identify the report format as PDF, word or excel.

                  public class SearchParameterModel
    {
        
            [Display(Name = "Search By Terrritory")]
            public string Territory
            {
                get ;
 
                set ;
            }
            public string Format
            {
                get;
 
                set;
            }
 
    }
            

WorldModel class is data structure of report result set. This will be later populate and bind report RDLC data source. One warning, do define private members in getter and setter properties otherwise RDLC dataset won't be able to identify the fields or column .It results into report error.

 public class WorldModel
    {
       
            private string m_Territory;
            private string m_Country;
            private string m_Year;
            private string m_Stats;
 
           
            public string Territory
            {
                get {return m_Territory ; }
 
                set {value = m_Territory;}    
            }
 
            public string Country
            {
                get { return m_Country; }
 
                set { value = m_Country; }
            }
 
            public string Year
            {
                get { return m_Year; }
 
                set { value = m_Year; }
            }
 
            public string Stats
            {
                get { return m_Stats; }
 
                set { value = m_Stats; }
            }
            public WorldModel()  { }
 
            public WorldModel(string territory, string country, string year, string stats)
            {
                m_Territory      = territory;
                m_Year   = year;
                m_Country = country;
                m_Stats = stats;
            }
    }




View

1. The view is simple form with input text with one button. We have image tag to rendered report in section. On button click we passed input values to controller using HttpPost-ActionResult

2. View is coupled with Strongly typed Model -->ViewModel . @model MvcApplication3.Models.SearchParameterModel

3. Container :We capture/store textfield value using @Html.TextBoxFor(m => m.Territory)

4. On button click we check Model collection object is populated or exist by invoking controller public ViewResult ReportViewer(SearchParameterModel um).This is called when httppost occured when button clicked.

5. Now the ***imp twist is , we now get value of input parameter back to view and is initialized in @Url.Action("GenerateAndDisplayReport", "Report", new { territory = Model.Territory, format = Model.Format }).. Check the @ if(Model !=null) 

The above workflow is bit tedious to understand at this point of time. All you need is to download source code and understand the flow of code execution. MVC is all about concepts and practice.





Controller

1. The ActionResult ReportViewer() is invoked for the first time on page load of Report form. i.e When we clicked onMenu report link.

2. The ActionResult ReportViewer(SearchParameterModel um) is invoked when form post takes place due to button clicked event.

3. FileContentResult GenerateAndDisplayReport(string territory, string format) is used to bind and populate img with response stream. Check view @URl.Action for more details.

 public class ReportController : Controller
    {
        //
        // GET: /Report/
        [AllowAnonymous]
        public ActionResult ReportViewer(string returnUrl)
        {
            ViewBag.ReturnUrl = returnUrl;
            return View();
        }
 
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ViewResult ReportViewer(SearchParameterModel um)
        {
            return View(um);
        } 
 
        public FileContentResult GenerateAndDisplayReport(string territory, string format)        
        {            
            LocalReport localReport = new LocalReport();            
            localReport.ReportPath = Server.MapPath("~/Content/Report1.rdlc");
            IList<WorldModel> customerList = new List<WorldModel>();
            customerList.Add(new WorldModel("Europe", "Sweden", "2001", "1823"));
            customerList.Add(new WorldModel("Europe", "Sweden", "2002", "1234"));
            customerList.Add(new WorldModel("Europe", "Sweden", "2003", "9087"));
 
            customerList.Add(new WorldModel("Europe", "Denmark", "2001", "6793"));
            customerList.Add(new WorldModel("Europe", "Denmark", "2002", "4563"));
            customerList.Add(new WorldModel("Europe", "Denmark", "2003", "1897"));
 
            customerList.Add(new WorldModel("Europe", "Norway", "2001", "5632"));
            customerList.Add(new WorldModel("Europe", "Norway", "2002", "9870"));
            customerList.Add(new WorldModel("Europe", "Norway", "2003", "2367"));
 
            customerList.Add(new WorldModel("Asia", "India", "2001", "1980"));
            customerList.Add(new WorldModel("Asia", "India", "2002", "9765"));
            customerList.Add(new WorldModel("Asia", "India", "2003", "6789"));
 
            customerList.Add(new WorldModel("Asia", "Japan", "2001", "9871"));
            customerList.Add(new WorldModel("Asia", "Japan", "2002", "2987"));
            customerList.Add(new WorldModel("Asia", "Japan", "2003", "1256"));
 
            customerList.Add(new WorldModel("North America", "United States", "2001", "9871"));
            customerList.Add(new WorldModel("North America", "United States", "2002", "9871"));
            customerList.Add(new WorldModel("North America", "United States", "2003", "9871"));
 
 
            customerList.Add(new WorldModel("North America", "Canada", "2001", "9871"));
            customerList.Add(new WorldModel("North America", "Canada", "2002", "9871"));
            customerList.Add(new WorldModel("North America", "Canada", "2003", "9871"));
 
            customerList.Add(new WorldModel("North America", "Mexico", "2001", "9871"));
            customerList.Add(new WorldModel("North America", "Mexico", "2002", "9871"));
            customerList.Add(new WorldModel("North America", "Mexico", "2003", "9871"));
 
            customerList.Add(new WorldModel("South America", "Brazil", "2001", "9871"));
            customerList.Add(new WorldModel("South America", "Brazil", "2002", "9871"));
            customerList.Add(new WorldModel("South America", "Brazil", "2003", "9871"));
 
            customerList.Add(new WorldModel("South America", "Columbia", "2001", "9871"));
            customerList.Add(new WorldModel("South America", "Columbia", "2002", "9871"));
            customerList.Add(new WorldModel("South America", "Columbia", "2003", "9871"));
 
            customerList.Add(new WorldModel("South America", "Argentina", "2001", "9871"));
            customerList.Add(new WorldModel("South America", "Argentina", "2002", "9871"));
            customerList.Add(new WorldModel("South America", "Argentina", "2003", "9871"));
            ReportDataSource reportDataSource = new ReportDataSource();
            reportDataSource.Name = "DataSet1";
            if (territory != null)
            {
                var customerfilterList = from c in customerList
                                         where c.Territory == territory
                                         select c;
 
                
                reportDataSource.Value = customerfilterList;
            }
            else
                reportDataSource.Value = customerList;
            
            localReport.DataSources.Add(reportDataSource);            
            string reportType = "Image";            
            string mimeType;            
            string encoding;            
            string fileNameExtension;                       
             
            Warning[] warnings;           
            string[] streams;            
            byte[] renderedBytes;             
            //Render the report            
            renderedBytes = localReport.Render(reportType, deviceInfo, out mimeType, out encoding, out fileNameExtension, out streams, out warnings);   
            //Response.AddHeader("content-disposition", "attachment; filename=NorthWindCustomers." + fileNameExtension); 
            if (format == null)
            {
                return File(renderedBytes, "image/jpeg");
            }
            else if (format == "PDF")
            {
                return File(renderedBytes, "pdf");
            }
            else {
                return File(renderedBytes, "image/jpeg");
            }
        }   }




6.Improvement Areas

The only problem with this solution is , it can not replace existing report viewer. The above solution is not robust as it rendered report as image in web form Razor view.



This need to be looked upon and html rendering option must be explored which I failed to achieve.Perhaps powerful web control like Report Viewer is missing in mvc razor architecture.

7. References

Report RDLC Design Tutorial

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

santosh poojari
Technical Lead
India India
Whatsup-->Exploring--> MVC/HTML5/Javascript & Virtualization.......!
www.santoshpoojari.blogspot.com

Comments and Discussions

 
Questiondeviceinfo PinmemberDavid Frostad6-Jun-14 6:49 
AnswerRe: deviceinfo PinmemberMember 110709105-Oct-14 20:26 
GeneralNice tutorial Pinmemberkennyomar6-Mar-14 5:15 
GeneralMy vote of 4 PinmemberMember 972113314-Jan-14 20:25 
Questionimplementation error PinmemberRavindra Pratap20-Nov-13 21:39 
Questionerror PinmemberRavindra Pratap20-Nov-13 21:39 
QuestionHow Open pdf in iframe not Image using this code PinmemberPradeepBind22-Aug-13 7:09 
AnswerRe: How Open pdf in iframe not Image using this code Pinmembersantosh poojari22-Aug-13 20:37 
GeneralMy vote of 5 PinmemberKrishnaReddy M21-Jun-13 1:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.1411022.1 | Last Updated 21 Jun 2013
Article Copyright 2013 by santosh poojari
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid