ASP.NET MVC and Chart Challenges

The ins and outs of using the Microsoft ASP.NET Chart control in an ASP.NET MVC web application

We do a lot of skijoring with our sled dogs during the winter. In this year of low snow and wildly fluctuating temperatures, it is sometimes a challenge to figure out where to go, where it isn't too cold for either us or the dogs. We'd troll from five to 10 weather sites, trying to get a feel for how the nearly inevitable winter inversion here in Fairbanks, Alaska, would affect our comfort while out. Clearly, it was time for a technology solution, a website that would pull together all the information we needed into a single, easy-to-read web page.

In line with my growing belief that ASP.NET MVC can be appropriate for just about any application you'd use any form of ASP.NET for (with varying degrees of increased or decreased work), I decided to use MVC. That is probably a bit of overkill, since it is just a single page with no user interaction at all. As you can see in the figure below, the site displays a table with various weather stations around Fairbanks, current conditions and the temperature change over the last hour, as well as a crude temperature gradient chart and Google map with the location of the stations. Behind the scenes, a WxStation class scrapes data from various source web pages, and a WxStationRepository provides a model interface for use with the MVC view. Everything is read in real time when a user loads or refreshes the page. This isn't very efficient, but it works for now. Later I may add features to save the readings to a database and check to see if the data is current without re-scraping the various web pages every time someone loads the page. I may need to do that if we add too many more weather stations to the list, so the page doesn't take too long to load.

The ASP.NET Chart Control
The temperature gradient chart uses Microsoft's ASP.NET Chart control for a quick and easy way to provide a visual representation of the data. (The primary feature that met the application requirements: It is free.) That worked well for the app, particularly since I had the option to use an in-memory stream for the resulting image, which is embedded in an element in the resulting page (with some of the random identifiers shortened to save space):

Temperature gradient

That saves the requirement of saving the image to a temporary directory; it can be hard to find an appropriate place given security limitations, particularly when using a shared hosting server.

Best of all, I could embed a <% %> code nugget in the view and use the same model data used for the table to generate the data points on the chart. I was even able to easily exclude any weather stations with stale data—defined in this application as more than two hours old—from the chart. (Stale data displays in the table, but is highlighted in red.) Simple to build, and nicely in line with the spirit of an MVC design, even though the Chart control is a server control. Separation of concerns is intact.

All pretty straightforward, free of rocket science, and a nice use of web technologies.

Deployment Challenges
Alas, all was not smooth and simple when I deployed the application to a shared hosting server on ORCSWeb. I love those guys, their technical support, and products, but their use of ISAPI_rewrite drives me up a wall sometimes. I just wasn't going to get that option to work without weird URLs, so I redeployed it to a client's web server with their kind permission. There I have full remote access control of the server, so I deployed MVC, the Chart control, and the application, and reset DNS to point to the new server.

Then I loaded up the site in my browser, and voila! An… error message. I ended up having two problems to solve.

The first problem was a No http handler was found for request type "POST" error, within the Chart code. This one was a bit of a head scratcher, because I wasn't using a POST with the control, just a GET. Thanks to stackoverflow.com, I discovered that in IIS 7 on Windows Server 2008 I had to use a Classic .NET AppPool instead of Integrated mode. When using Integrated mode, the chart image just would not display, no way, no how. I checked and rechecked the settings in web.config in the section for the HTTP handler, but nothing seemed amiss there. Nothing in the code seemed to make any difference either, including playing with various image locations instead of using UseHttpHandler for the Chart's ImageStorageMode property.

What's a bit disturbing is that I didn't find any documentation saying that Classic mode is required for using the Chart control. So that didn't make any sense. Nevertheless, I changed to Classic mode and moved on, for now. (Keep reading!)

But in Classic mode, now my MVC routes weren't working. Not a big deal for the default Home view, but the About view has some information about where the data is coming from, quirks in weather data in the Tanana Valley around Fairbanks, and some acknowledgments. I'm not using anything special for routing, just the default for a new MVC project:

routes.IgnoreRoute("\\{resource\\}.axd/\\{*pathInfo\\}");
routes.MapRoute(
     "Default",
     "\\{controller\\}/\\{action\\}/\\{id\\}",
     new \\{ controller = "Home", action = "Index", id = "" \\}
);

Solving the Problem
Back to Google, which led me to a very helpful page of the ASP.NET MVC tutorial: Using ASP.NET MVC with Different Versions of IIS (there is a VB version available as well). That tutorial discloses how to use MVC in Classic mode. You have two options: creating extensions to the route table or creating a wildcard script map. I decided against the first method because I have full access to the web server (as opposed to it being a shared hosting server) and because it makes the URLs rather funky.

The wildcard script map simply requires adding a map for all web server requests to the ASP.NET Framework for this application. That isn't something that will work for all applications, but for this simple app it was fine. The procedure is detailed in the tutorial I referenced, and is pretty simple. It involves using the Handler Mappings applet in IIS Manager for the application, and mapping * (all requests) to aspnet_Isapi.dll.

That solved the routing problem, and the chart still displayed properly. Happiness!

Final Resolution
Happiness indeed, but, alas, I just couldn't let it end there. It just didn't seem right that I couldn't use Integrated mode with its better performance and features. Both the Chart controls and MVC are pretty new out of Microsoft, so I couldn't believe that either product would require moldy Classic mode.

Lo and behold, the problem was that some of the documentation for the Chart control is wrong. You need to add the handler in web.config not to the section, but to the newer section. Here is that part of my config file:

There IIS 7 knows what to do with it, and I could switch back to Integrated mode and remove the wildcard script map, and true joy and warm skijoring bliss were mine at last.

I hope that my pain in getting this all working together correctly saves you from the same pain! But it is always interesting to me how all this stuff works together, sometimes to befuddle me and sometimes to delight me!

Don Kiely ([email protected]), MVP, MCSD, is a senior technology consultant, building custom applications and providing business and technology consulting services. His development work involves tools such as SQL Server, Visual Basic, C#, ASP.NET, and Microsoft Office.

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish