| By Kevin Hoffman | Article Rating: |
|
| October 2, 2009 12:17 PM EDT | Reads: |
817 |
When we all build websites, usually we're concerned with figuring out how we're going to get the major entities into the view. We want to know how we're going to handle the shopping cart or how we're going to get the customer record onto the page, etc. But, one of the little details that almost always comes back to bite us in the ass is the use of reference data.
Reference data is data that rarely changes, is frequently queried, and shows up in multiple places throughout the application. This might be anything from the list of companies currently trading on a particular stock market if you're building a financial web application or things like the list of countries, states, cities, counties, tax rules, and shipping tables if you're doing fulfillment of orders online.
The problem is we rarely think about reference data ahead of time, so what usually happens is our strategy for handling reference data becomes an ugly pile of spaghetti and we have some controls doing their own queries to get reference data and some pages doing it and some services - it's a mess.
It would be awesome if we could have our controller methods declare ahead of time what reference data the view is going to need and then the view will simply have that data when it renders - completely abstracting the manual fetching of reference data for dropdownlists and other lookups. This centralization of reference data handling also gives us the ability to control the cache lifetimes of reference data items individually.
Thankfully ASP.NET MVC lets us do this easily. All we have to do is create our own action filter attribute. For example, let's say we've got a Customer controller and we're building the Edit(int id) method. Our customer view model objects are normalized enough so that they have IDs on them for country, customer type, and membership type (totally contrived examples, don't diss my domain knowledge of CRMs...). A sample edit method might look like this:
[RequireReferenceData(ReferenceDataKey = ReferenceDataKeys.Countries)]
[RequireReferenceData(ReferenceDataKey = ReferenceDataKeys.CustomerTypes)]
[ReqiureReferenceData(ReferenceDataKey = ReferenceDataKeys.MembershipTypes)]
public ActionResult Edit(int id)
{
Customer cust = customerRepository.GetCustomerByKey(id);
return View(cust);
}
The beauty of this approach is that anyone reading your code will immediately know that the view being rendered is going to depend on having 3 different types of reference data lists made available, as well as the core Customer object itself. Compare how easy this is to read and maintain to a classic .ASPX page where you might have the countries lookup being loaded by a custom dropdown box and the customer types lookup being loaded by the page and the membership types being loaded by yet another pile of spaghetti elsewhere.
To create the RequireReferenceDataAttribute class, all you need to do is inherit from ActionFilterAttribute and override the OnExecuting method. In this method you would just fetch the reference data and store it in the ViewData dictionary like this:
context.Controller.Model.ViewData[ReferenceDataKey] = (data fetched from elsewhere...);
And then in your view you can do something like this:
<%= Html.DropDownList("CustomerTypeId",
(IEnumerable<SelectListItem>)ViewData[ReferenceDataKeys.CustomerTypes]) %>
And you're all set. The main moral of this story is to never underestimate the power of action filters. With ASP.NET MVC, if you want your intent to be more declarative and you want your code to be more readable, chances are you're only a few lines of code away from where you want to be.
Read the original blog entry...
Published October 2, 2009 Reads 817
Copyright © 2009 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Kevin Hoffman
Kevin Hoffman, editor-in-chief of SYS-CON's iPhone Developer's Journal, has been programming since he was 10 and has written everything from DOS shareware to n-tier, enterprise web applications in VB, C++, Delphi, and C. Hoffman is coauthor of Professional .NET Framework (Wrox Press) and co-author with Robert Foster of Microsoft SharePoint 2007 Development Unleashed. He authors The .NET Addict's Blog at .NET Developer's Journal.
- Kindle 2 vs Nook
- Installing Geneva Beta 2 on Windows 7
- Binary Serialization and Azure Web Applications
- Get Your Red Hot VS2010 Beta 2
- Templated Helpers in ASP.NET MVC 2 (VS2010 Beta 2 Version)
- LINQ to SQL and Entity Framework on top of SQL Azure
- Working with Table Storage on the Windows Azure
- ADO.NET Data Services Projections Makes Sliced Bread Jealous
- Creating and Manipulating Your SQL Azure Database
- Setting up an ASP.NET MVC 2 Application for Windows Azure
- Breaking Changes for .NET Services in Azure
- Windows Identity Foundation (WIF) Release Candidate Is Out
- Kindle 2 vs Nook
- The Difference Between Web Hosting and Cloud Computing
- ASP.NET Membership Provider in the Cloud
- Binary Serialization and Azure Web Applications
- Installing Geneva Beta 2 on Windows 7
- Get Your Red Hot VS2010 Beta 2
- Templated Helpers in ASP.NET MVC 2 (VS2010 Beta 2 Version)
- LINQ to SQL and Entity Framework on top of SQL Azure
- Using ASP.NET MVC Action Filters to Declare Reference Data for Views
- Creating Correlated Workflow Services in WF4 / .NET4 : Part 1
- Working with Table Storage on the Windows Azure
- ADO.NET Data Services Projections Makes Sliced Bread Jealous
- Want to Learn How to Write iPhone Applications?
- iPhone Will Make Mobile AJAX and Web 2.0 Happen
- Will Silverlight Be DOA?
- Why Build Applications for the iPhone and iPod Touch?
- Silverlight 2 - Adobe Flex Killer Is on Its Way!
- Why Is iPhone Better? Here's My Story...
- Silverlight and Astoria - First Impressions
- iPhone Developer Summit 2008 East
- Is the Silverlight Adoption Rate Artificially Inflated?
- iPhone with High-Speed G3 Support at Macworld
- Will Google's Android Sink or Swim?
- iPhone Price Cut? Here is My Objective View on This!

























