One of the latest features found in ASP.NET MVC RC is the ability to return files from a Controller ActionResult. This is now possible due to the new FileResult class and a File helper method found in the Controller base class. The File method is overloaded and allows content to be returned based on a file path, stream or byte array. The mime type can also be set, as well as optionally setting the file name to allow the user to download the file.
This powerful new feature makes it easy to work the the new ASP.NET Chart control without having to rely on writing custom Http Handlers. To begin working with the chart control in your MVC projects you'll need to download and install the control. I also recommend downloading the sample project, documentation, and Visual Studio add-on. It sample project has over 200 samples, but since this is a WebForm control you'll be using the API to generate your charts and generating image files.
Once the chart control is installed you'll need to a add reference to the following assembly:
System.Web.DataVisualization
You'll also need the following namespaces:
using System.Web.UI.DataVisualization.Charting;
using System.Drawing;
using System.IO;
Here is a basic pattern for rendering a chart:
1: public ActionResult SimpleChart()
2: { 3: // Create Chart object
4: Chart chart = new Chart();
5:
6: // TODO: Set Chart Properties and Add Data
7:
8: // Save Chart to MemoryStream
9: MemoryStream ms = new MemoryStream();
10: chart.SaveImage(ms, ChartImageFormat.Png);
11:
12: // Return Binary Array using File helper method
13: return File(ms.GetBuffer(), @"image/png");
14: }
There is actually a lot of properties to set to get chart to render, but this is basic idea. Once you have an ActionResult for your chart you can simple reference it through an image tag where the source is the /{controller}/{action}/{optional parameters}. For example:
<img src="/Chart/SimpleChart" alt="Sample Chart" />
Here is a complete example:
1: public ActionResult SampleChart()
2: { 3:
4: Chart chart = new Chart();
5: chart.Height = 296;
6: chart.Width = 412;
7: chart.ImageType = ChartImageType.Png;
8: chart.Palette = ChartColorPalette.Excel;
9: chart.BackColor = Color.Cornsilk;
10: chart.RenderType = RenderType.BinaryStreaming;
11: chart.BorderlineDashStyle = ChartDashStyle.Solid;
12: chart.BackGradientStyle = GradientStyle.TopBottom;
13: chart.BorderlineWidth = 2;
14: chart.BorderlineColor = Color.Blue;
15: chart.BorderSkin.SkinStyle = BorderSkinStyle.Emboss;
16: chart.AntiAliasing = AntiAliasingStyles.All;
17: chart.TextAntiAliasingQuality = TextAntiAliasingQuality.Normal;
18:
19: Title title = chart.Titles.Add("Main"); 20: title.Text = "Sample Random Data";
21: title.Docking = Docking.Top;
22: title.Font = new Font(FontFamily.GenericSerif, 25, FontStyle.Regular);
23:
24: Series series1 = chart.Series.Add("Series1"); 25: series1.ChartType = SeriesChartType.Column;
26: series1.YValueType = ChartValueType.Int32;
27: series1.LegendText = "Dates";
28: series1.BorderColor = Color.Azure;
29: series1.ShadowOffset = 2;
30:
31:
32: // Generate random data for chart.
33: Random randomGen = new Random();
34: int dataSize = randomGen.Next(10, 20);
35: for (int i = 0; i < dataSize; i++)
36: { 37: string legendText = string.Format("DP {0}", i); 38: Double dataValue = (double)randomGen.Next(1000);
39: series1.Points.Add(new DataPoint()
40: { 41: YValues = new Double[] { dataValue }, 42: LegendText = legendText
43: });
44: }
45:
46: ChartArea chartArea = chart.ChartAreas.Add("Default"); 47: chartArea.BackColor = Color.Transparent;
48: chartArea.BorderColor = Color.Red;
49: chartArea.AxisX.IsMarginVisible = true;
50: chartArea.Area3DStyle.Enable3D = true;
51:
52: MemoryStream ms = new MemoryStream();
53: chart.SaveImage(ms);
54:
55: return File(ms.GetBuffer(), @"image/png");
56: }
I have created a demo project with the above example as well as an example using data using Linq To Sql. There is also a controller for creating test data in the event you want to expand my demo for your own study. Feel free to download it and reuse any parts in your own projects.
I gave a presentation last Wednesday that was a continuation of Greg Pugh's talk on building a Wish List application using ASP.NET MVC. I demonstrated how to replace the embedded LINQ To SQL code with a domain model and separate service layer using a repository pattern and programming against interfaces. The remainder of the talk was centered around how use the latest features of RC1 to build the Wish List application. The code from my talk can be downloaded here. Also check out ScottGu's excellent post on RC1.
As promised here is the code from last night's presentation. Thanks to all who attended. Next month we'll continue to expand on this theme of building a data-centric Silverlight application. We'll attempt to tackle master-detail, validation, and maybe security.
I'll be giving another presentation on Wednesday for the TRINUG Web Application focus group at Channel Advisor (map). This will be a follow up form my last presentation a couple of months ago on data binding. I'll be walking through creating a simple WCF service for handling CRUD operations to a SQL Express database using LINQ. Then consuming the service in a Silverlight application.
In the last presentation we had enough people with laptops that it evolved into a hands-on lab which I thought turned out great. Things moved a little slower, but much more fun than looking at a Power Point card deck! I am hoping we do that again. To help with that the starting project can be downloaded here. It is just the base web project with a SQL Express database. To test it just build and run the project. You should see a grid view with three records.
There is a new developer tool from Microsoft that focus on helping developers produce consistent code for layout, readability and documentation. It comes with 200 best practice rules that are compatible with the default layout settings in both Visual Studio 2005 and Visual Studio 2008.
For more details:
http://code.msdn.microsoft.com/sourceanalysis
http://blogs.msdn.com/sourceanalysis
After spending most of the morning giving this a spin I am glad to finally have something to help keep me in line. I don't completely agree with all of the rules but I am willing to try anything to help me be a better developer.