Jeffrey Palermo (.com)

Sponsors

The Lounge

News

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
ASP.NET MVC: Goodbye SmartBag, Hello ViewDataExtensions

A while back, I thought up the idea of the SmartBag, which has a very friendly API for working with viewdata objects.  With the December CTP, adding objects to ViewData was a bit difficult, but now that the ViewData property is an IDictionary on the Controller base class, getting objects in is very easy.  If you like this post, subscribe to my feed at http://feeds.feedburner.com/jeffreypalermo.

Consider the following usage

[Test]
public void ShouldRetrieveSingleObjectByType()
{
    var bag = new Dictionary<string, object>();
    var url = new Url("/asdf"); //arbitrary object
    bag.Add(url);
 
    Assert.That(bag.Get<Url>(), Is.EqualTo(url));
    Assert.That(bag.Get(typeof(Url)), Is.EqualTo(url));
}

We are adding a Url object to the dictionary, and then we can retrieve the object through the Get<T> method or by passing the type.  No need for a string key if only a single Url is in the dictionary.  If you have multiple Url objects, you can fall back to keys, or you can pass in a Url[] and then Get<Url[]>(). 

In CodeCampServer, I've removed SmartBag and added these ViewDataExtensions.  These are extension methods to IDictionary<string, object> and System.Web.Mvc.ViewData.  In my opinion, System.Web.Mvc.ViewData should inherit from Dictionary<string, object>, so maybe that will happen in the next release.

I've added ViewDataExtensions to MvcContrib, so you you'd like to use them, just build the trunk of MvcContrib, and you'll have them.  Look at CodeCampServer for widespread use of these extension methods.  Strongly typed views don't scale when the application complexity increases, but these view data extensions make working with the dictionary a snap.  My annoyance factor is very low with viewdata now.

MvcContrib is a free, open-source project.  Feel free to use it and contribute patches to it.  Building it takes less than 1 minute on my box, and the build runs all 840 unit tests to verify the features continue to work.


Posted 03-26-2008 3:42 PM by Jeffrey Palermo

[Advertisement]

Comments

Victor Kornov wrote re: ASP.NET MVC: Goodbye SmartBag, Hello ViewDataExtensions
on 03-26-2008 6:20 PM

>Strongly typed views don't scale when the application complexity increases

Care to elaborate?

Steve Sanderson wrote re: ASP.NET MVC: Goodbye SmartBag, Hello ViewDataExtensions
on 03-27-2008 11:39 AM

> >Strongly typed views don't scale when the application complexity increases

> Care to elaborate?

They've been fine for me so far. What don't you like about them?

> In my opinion, System.Web.Mvc.ViewData should inherit from Dictionary<string, object>

Would be interested to know why. The current behavior supports more flexible late binding than would be possible with Dictionary<string,object>.

Greg wrote re: ASP.NET MVC: Goodbye SmartBag, Hello ViewDataExtensions
on 03-27-2008 11:45 AM

   Assert.That(bag.Get<Url>(), Is.EqualTo(url));

   Assert.That(bag.Get(typeof(Url)), Is.EqualTo(url));

Can you explain why you use two asserts here?

How about:

Assert.IsTrue(bag.Get<Url>() == url);

The code as presented seems really weird to me ... are you worried that there may be an overriden comparison? Even if there is and it says the objects are the same when they are actually different shouldn't you be honoring that?

Greg wrote re: ASP.NET MVC: Goodbye SmartBag, Hello ViewDataExtensions
on 03-27-2008 12:46 PM

oops ... read it wrong ... I was looking through the old tests which did the assert on equality and type ... not this one .... my bad

Jeffrey Palermo wrote re: ASP.NET MVC: Goodbye SmartBag, Hello ViewDataExtensions
on 03-27-2008 11:09 PM

@Victor,

No here.  Perhaps in another post.

Jeffrey Palermo wrote re: ASP.NET MVC: Goodbye SmartBag, Hello ViewDataExtensions
on 03-27-2008 11:10 PM

@Steve,

>Would be interested to know why. The current behavior supports more flexible late binding than would be possible with Dictionary<string,object>.

Inheriting from Dictionary<string, object> would not take away any of the current capabilities.  It would, however, add IEnumerable so we could explore the contents freely.

James Arendt wrote re: ASP.NET MVC: Goodbye SmartBag, Hello ViewDataExtensions
on 03-28-2008 10:53 AM

@Jeff:

Both the generic and non-generic versions of the IDictionary interface inherit IEnumerable interfaces.

Jeffrey Palermo wrote re: ASP.NET MVC: Goodbye SmartBag, Hello ViewDataExtensions
on 03-28-2008 11:17 AM

@James,

That is correct.  And that's a main reason why System.Web.Mvc.ViewData should implement IDictionary.

James Arendt wrote re: ASP.NET MVC: Goodbye SmartBag, Hello ViewDataExtensions
on 03-28-2008 2:21 PM

For some reason, I had it in my head that ViewData already did implement IDictionary when I first read through your post.

So, it did not make sense why inheriting from Dictionary would provide any benefit. But, ViewData does not implement any interfaces including IDictionary.