ASP.NET MVC: Creating reports using Chart control

ASP.NET Chart control is powerful control you can use to add charting support to your web applications. Although chart controls are mainly used with ASP.NET forms it is not very hard to use them also in ASP.NET MVC applications. In this posting I will show you how to use ASP.NET Chart control in ASP.NET MVC application and I will illustrate how to do it easily so you don’t mess up your views.

Before we start coding I want to make some notes about my solution:

  • this solution is pretty new and it is sure that one can improve the code provided here,
  • using this solution I’m trying to generalize in-place reporting for MVC applications,
  • also I’m trying to keep my views as clean as possible – chart definitions are not small if you have more complex charts or if you want very nice looking charts.

If you are not familiar with ASP.NET Chart control then please read my blog posting<asp:Chart>. You find there simple introduction to this free control and also all necessary links.

Solution overview

What we are trying to build here is shown on the following diagram. Our main goal is to avoid using ASP.NET forms elements in our MVC line user interface. Also we want to generalize reporting support so we have one interface for all reports.

ASP.NET MVC chart control flow

I introduce here pretty simple report. If you have more complex reports then you can extend reporting interface shown below later. You may also find useful to reorganize outputing system. I am using here simple works-for-me or works-for-prototyping solution. I want to focus on point and let’s try not to lose it.

Reporting interface

Before we create our first report let’s define interface for it. This interface must define all basic actions we need to do with reports:

  • set source with report data,
  • bind data to report,
  • write report image to some (output) stream.

This is my reporting interface. Note that DataSource has only setter – it is because I don’t have currently need to ask data from chart. I only provide data to it.

public interface IReportControl : IDisposable
object DataSource { set
; }
void SaveChartImage(Stream stream);

As you can see this interface is pretty thin. I am sure that it will grow in the future when need for more complex reports appears.

Sample report

Let’s define one report for testing purposes. Add web user control called MyReport.ascx to Reports folder of your web application and drag ASP.NET Chart control on it. Here is definition of my control.

<%@ Control Language="C#" AutoEventWireup="true" 
@ Register 
assembly="System.Web.DataVisualization, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

<asp:Chart ID="Chart1" runat="server" Palette="Excel"
    Height="200px" Width="200px">
        <asp:Series Name="Series2"
            Font="Microsoft Sans Serif, 8pt"
LabelBackColor="255, 255, 192"
            LabelBorderColor="192, 192, 0"
        <asp:ChartArea Name="ChartArea1" BorderDashStyle="Solid">
IntervalType="Days" />
Font="Microsoft Sans Serif, 8pt, style=Bold"
            Text="Last week enquiries">

If you look at the definition and consider it as simple one you understand why I don’t want this mark-up to be there in my views. This is just one simple report. But consider for a moment three complex reports. 90% of my view will be one huge report definition then and I will miss all the good things that views have.

As I want this report to be interfaced with my reporting mechanism I make it implement IReportControl interface. Code-behind of my control is as follows.

public partial class LastEnquiriesChart : UserControl, IReportControl
public object
            Chart1.DataSource =

public override void

public void SaveChartImage(Stream stream)

All other user controls we are using for reporting must also implement IReportControl interface. This leads us to one interesting finding – we don’t have to host only chart control in our user controls, we have to host there whatever ASP.NET forms control we need for reporting. We can also create wrapper controls that get report image from some other external source (let’s say we have some COM component that is able to return reports as images).

Creating loader

Now we have sample report control and interface we can use to provide data and catch output of report. It is time to create meeting place for two worlds: ASP.NET forms and ASP.NET MVC framework. I created class called ReportLoader. The name of this class is good enough for me because it tells me that this is the integration point between two worlds. Let’s look at loader implementation now.

public static class ChartLoader
public static void SaveChartImage(string controlLocation, IEnumerable data, Stream
using (var page = new Page
using (var control = (IReportControl
"~/Reports/" + controlLocation))
            control.DataSource = data;

Loader does one trick: it doesn’t render the control. It only runs as long as report is written to stream and then it disposes user control and temporary page instance to avoid all other actions they may take. I made ChartLoader and SaveChartImage methods as static because I don’t need hell load of classes and super-cool architecture right now.

Creating controller action

We are almost there… Let’s create now controller action that returns chart image. As I am prototyping my application I use very robust controller action. You may be more polite coders and I strongly suggest you to read Bia Securities blog posting BinaryResult for Asp.Net MVC. You can find BinaryResult implementation also from MVC Contrib project.

public ActionResult
var repository = Resolver.Resolve<IPriceEnquiryRepository
enquiries = repository.ListPriceEnquiries();
var data = from p in
group p by p.Date.Date into
select new
{ Date = g.Key, Count = g.Count() };

    Response.ContentType =

return null; // have to return something

Now we have controller action that asks data from somewhere, prepares it for report and asks report as image from ChartLoader. Before outputing the report Response is cleared and content type is set to PNG. After writing image to response output stream the response is ended immediately to avoid any mark-up that may be written there otherwise.

As you can see I created special automatic objects for reporting. If you look at my report definition you can see that x-axis is bound to Date and y-axis to Count. You can also prepare reporting data in some near-DAL class methods and then slide this data through controller to report. The choice is yours.

Adding report to view

Chart exampleNow let’s link report to view. We just have to add one simple img tag to our view and make it src to call out GetChart() method defined above.

src="<%= Url.Action("GetChart")%>"
alt="Last week enquiries"
title="Last week enquiries" 

Output of report is shown on right. I don’t have much data here and my report is not very nice but it works. Now, if you are not too tired or bored, it is time to make your chart very nice and show it to your boss or customer.


Mixing forms and MVC worlds of ASP.NET doesn’t always have to end up with hard mess. In this posting I showed you how to add simple but pretty generic reports support to your ASP.NET MVC application. Due to good interfacing we achieved separation between forms and MVC templates and linking reports to views is very-very simple.

Of course, code and interfaces represented here are not production-ready examples. But they give you right direction and you can always improve design of my solution. My point was to illustrate how to mix MVC and forms world in

Gunnar Peipman

Gunnar Peipman is ASP.NET, Azure and SharePoint fan, Estonian Microsoft user group leader, blogger, conference speaker, teacher, and tech maniac. Since 2008 he is Microsoft MVP specialized on ASP.NET.

    17 thoughts on “ASP.NET MVC: Creating reports using Chart control

    • November 21, 2009 at 6:26 pm

      Nice article.

      Didnt know that we can use the UserControl can be used in this way to do a dirty work and save the chart image. Thanks for the article :)

    • December 8, 2009 at 5:13 pm

      This sounds great for a stateless implementation. But doesn’t using an image handler give you caching capabilities? I guess I am confused as to why this way is better than using an image handler?

    • December 8, 2009 at 11:04 pm

      Is the image loaded asynchronously with the page? Also, does IIS cache this image as you can when using an HTTP ImageHandler?

    • December 11, 2009 at 9:47 pm

      Hi Chuck! Sorry for late answer. The solution provided here is just to give you some idea how to mix separate ASP.NET frameworks so this mix doesn’t happen in same files and modules.

      Of course, you can use this code as base and add caching if necessary etc. You can also use image handler – no problem. Using image handler and caching is more like optimization topic and I wasn’t sure if it is good idea to cover this topic too as this posting is long enough.

    • January 26, 2010 at 2:52 am

      This post is wonderful. It is just what I want. Thank you.

      I also would like to export the chart to excel using OpenXML. Do you have an example to share?

    • January 28, 2010 at 8:55 am

      Thanks for feedback, Mei :)

      Currently I have no good example for charting in Excel. As soon as I invent something I will write about it.

    • September 28, 2010 at 9:00 pm

      Could you put a complete project code on the page so I can download and try it?

    • November 17, 2010 at 3:56 pm

      Thanks for the tutorial. It’s very helpful in being able to switch out chart images on the fly. But what I found with this solution is that you can’t have any client-side interactivity with it (because it’s an image). For example, if I want to show a tooltip of the (x,y) of the position when the mouse hovers over it… can’t do that with an image.

      In this case I guess I’ll have to use control in an iframe or something…. so I can both switch it out on the fly and have client-side interactivity… I’ll try it. Thanks for the example.

    • December 14, 2010 at 5:24 pm

      This is the only line I’m having trouble with

      1. Revsolver is unknown
      2. IPriceEnquiryRepository is unknown

      Thus am I missing an Interface ?

      I’m using 3.5 sp1 mvc2



    • December 14, 2010 at 6:42 pm

      Resolver and IPriceEnquiryRepository are just example types. Resolver is shortcut method to some IoC/DI container that returns you object by interface. You can play it around if you need or you can use some IoC/DI container like Unity, StructureMap, NInject etc.

    • January 7, 2011 at 3:49 pm

      MVC 2 and above includes the File Action Result so the GetChart Controller action could be modified as follows:

      var ms = new MemoryStream();
      return File(ms.GetBuffer(), “image/png”);

    • March 9, 2012 at 12:19 pm

      Great post thanks.

    • May 9, 2012 at 8:15 pm


      Thanks for a great article!!… I’ve gotten somewhere but I’d love to see the project if you have a sample.


    • Pingback:ASP.NET MVC 3 Beta: Built-in support for charts | Gunnar Peipman - Programming Blog

    • Pingback:ASP.NET MVC: Creating user configurable charts | Gunnar Peipman - Programming Blog

    • May 23, 2019 at 2:04 am

      Hi, my friend, thanks a lot for this great article , help me a lot.


    Leave a Reply

    Your email address will not be published. Required fields are marked *