Click here to Skip to main content
15,884,746 members
Articles / Programming Languages / Razor
Article

Prototype MVC4 Razor ReportViewer? RDLC

Rate me:
Please Sign up or sign in to vote.
4.83/5 (25 votes)
20 Jun 2013CPOL4 min read 178K   13.3K   41   16
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.



Image 1

Image 2

 



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

Image 3

 



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



Image 4



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.

Image 5

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

Image 6



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.

C#
              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.

C#
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.

Image 7



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.

C#
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)


Written By
Technical Lead
Australia Australia
Whatsup-->Exploring--> MVC/HTML5/Javascript & Virtualization.......!
www.santoshpoojari.blogspot.com

Comments and Discussions

 
Generalthank you for sharing your sample application Pin
MaoNY26-Feb-18 15:50
MaoNY26-Feb-18 15:50 
SuggestionNice tutorial, But Error in Download PDF Pin
Alexandro Múnera27-Apr-16 7:15
Alexandro Múnera27-Apr-16 7:15 
QuestionCode Flaw Pin
Member 1174073327-Mar-16 1:46
Member 1174073327-Mar-16 1:46 
QuestionThank you very much Pin
Member 115810038-May-15 8:25
Member 115810038-May-15 8:25 
QuestionExcellent article Pin
kiran kanipakam2-Jan-15 8:58
kiran kanipakam2-Jan-15 8:58 
QuestionThank you Pin
kiran kanipakam23-Dec-14 11:50
kiran kanipakam23-Dec-14 11:50 
Thank you. Good article !!!
Questiondeviceinfo Pin
David Frostad6-Jun-14 5:49
David Frostad6-Jun-14 5:49 
AnswerRe: deviceinfo Pin
Member 110709105-Oct-14 19:26
Member 110709105-Oct-14 19:26 
GeneralRe: deviceinfo Pin
aminkh1727-Dec-15 18:02
aminkh1727-Dec-15 18:02 
GeneralNice tutorial Pin
kennyomar6-Mar-14 4:15
kennyomar6-Mar-14 4:15 
GeneralMy vote of 4 Pin
Member 972113314-Jan-14 19:25
Member 972113314-Jan-14 19:25 
Questionimplementation error Pin
Ravindra Pratap20-Nov-13 20:39
Ravindra Pratap20-Nov-13 20:39 
Questionerror Pin
Ravindra Pratap20-Nov-13 20:39
Ravindra Pratap20-Nov-13 20:39 
QuestionHow Open pdf in iframe not Image using this code Pin
PradeepBind22-Aug-13 6:09
PradeepBind22-Aug-13 6:09 
AnswerRe: How Open pdf in iframe not Image using this code Pin
santosh poojari22-Aug-13 19:37
santosh poojari22-Aug-13 19:37 
GeneralMy vote of 5 Pin
KrishnaReddy M21-Jun-13 0:19
KrishnaReddy M21-Jun-13 0:19 

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

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