CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Kyle Baley - The Coding Hillbilly

"We are stuck with technology when what we really want is just stuff that works" -- Douglas Adams

Getting ASP.NET MVC to do the dirty work

Hey, whaddaya know! I have some actual feedback to give on something in the form of "boy, I wish the product could do X". Who knew I had evaluation skillz?

The product is ASP.NET MVC and I'm implementing some pretty standard functionality: Get the data from the user and save it in the database. For this post, we'll call the object being saved a Critter.

One of the properties on a Critter is Species and its value is selected from a dropdown list. This is not such a far cry from Scott Guthrie's equally descriptive Product/Category example which is an okay example if you're looking only for education and not entertainment.

Like Scott's version, I'm passing what amounts to a DTO as the ViewData. The DTO includes a list of Species to select from as well as the actual Critter object. You fill in the name of the critter, select your species, and click Save and watch the magic happen in the form of saving the Critter to the database.

Now, according to the tutorial, there are two ways to create your Critter object in the Create action. The first way is to specify a method parameter for each property. For example:

[ControllerAction]
public void Create( string CritterName, int SpeciesID )
{
    Critter critter = new Critter( );
    critter.Name = CritterName;
    critter.SpeciesID = SpeciesID;
    // Do "stuff" with the critter
}

The second way is shorter and possibly cleaner:

[ControllerAction]
public void Create( )
{
    Critter critter = new Critter( );
    critter.UpdateFrom( Request.Form );
    // Do "stuff" with the critter
}

This one is kinda cool if a little too magic. Updating from a NameValueCollection sounds like it might be fragile but they seem to have a good collective head on their shoulders so that might not be a concern.

Here's where my wish list comes in. Neither of these methods are how I would code the thing if I were doing it in, say, a Windows app. Ideally, I'd like to be able to do this:

[ControllerAction]
public void Create( ICritter critter )
{
    // Do "stuff" with the critter
}

That is, I'd like the framework to create my critter for me. It can do this for primitive types but not so much with objects. Admittedly, this is probably a tall order without getting back into a ViewState state of being but a hillbilly can dream, can't he?

Kyle the Utopian


Published Feb 25 2008, 05:50 PM by Kyle Baley
Filed under:

Comments

Pat Gannon said:

That does seem like a desirable feature.  It seems like that would be possible if you could configure the MVC framework to know how to hook into your DI container...  It seems like Windsor/StructureMap/Unity should be able to instantiate "complex" arguments if the MVC Framework knew how to talk to it before calling a controller method.

# February 25, 2008 6:11 PM

shawn said:

I don't know if you've seen this, but what do you think about how MonoRail solves the problem?

www.castleproject.org/.../smartcontroller.html

# February 25, 2008 6:57 PM

Kyle Baley said:

@shawn

Oh good, I was told that Monorail supported this and was hoping would chime in with the info so I didn't need to find it myself. And after looking through it, it does look familiar from the brief period when I looked at Monorail.

It's kinda funky doing it by specifying an attribute on the method parameter. Still not as clean as having it done for you. But it's closer to what I want than the ASP.NET MVC mechanism. At least the code will look nicer in the tests.

# February 25, 2008 9:41 PM

Rob said:

I have to chime in and say that the way Monorail supports this is sweet.  It just makes web development a pleasure.  It would be a major thumbs down if they didn't support something similar in ASP.NET MVC.  Perhaps we'll see more stuff like this in the next release.

# February 25, 2008 10:49 PM

Ken Egozi said:

Im actually quite surprised that the ASP.NET MVC / MvcContrib didn't come up yet with the equivalent to MonoRail's  SmartDispatcherController stuff. I wish I had some free time to do so.

# February 26, 2008 4:04 AM

Daily Bits - February 26, 2008 | Alvin Ashcraft's Daily Geek Bits said:

Pingback from  Daily Bits - February 26, 2008 | Alvin Ashcraft's Daily Geek Bits

# February 26, 2008 9:31 AM

Justice~! said:

I didn't realize you had access to UpdateFrom(Request.Form).  Honestly, I've looked for it but cant seem to call it!  What am I missing?  

# February 26, 2008 12:25 PM

Ben Scheirman said:

Isn't that part of MVCToolkit Justice?

@Kyle:  that's a killer feature and it's definitely attainable.  One thing you might need to consider is that often times we are updating a record, so the critter that comes in must have already been fetched from the repository and the properties set on top of that.

This might work if your IController implementation could look in the IoC container for a IRepository<ICritter>  (where ICritter is the type of the parameter) and then fetch it using the id from the request collection.

While that seems very cool and magic, I'm worried that it is way too much convention.  The minute you deviate from the norm it becomes cloudy.

# February 27, 2008 3:11 PM

Kyle Baley said:

@Ben: It very much is based on heavy use of convention. Reviewing the Castle documentation on how they handle this, you need to make sure your HTML elements are named appropriately. And that includes handling complex object graphs. Changing property names will wreak much havoc, especially since things like ReSharper's rename (and probably even Visual Studio's built-in one) won't change these in your HTML files.

But I'm good with that. I'm not big on arguments that amount to which tradeoff you're willing to live with. In this case, I'm having to change the design I want to use. If the other option was available, I'd use it and take the chance that maaaaybe I'd rename the Age property to Ripeness at a later date and have some work to do.

# February 27, 2008 3:56 PM

Ben Scheirman said:

After looking at Monorails documentation on this, I don't see this being used in an "Update" action, only create.  Do you think that the convention I proposed is worthwhile?

# February 28, 2008 10:42 AM

Chris Ortman said:

@Ben: If you are using ActiveRecord + MonoRail you can do an update using the ARDataBind attribute. It will look for the PrimaryKey, fetch the object from the database and then do the update.

# March 4, 2008 1:52 PM

Kyle Baley - The Coding Hillbilly said:

Here&#39;s the bad thing about ASP.NET MVC. Every little thing about it is bloggable mostly because every

# March 4, 2008 11:57 PM

Kyle Baley - The Coding Hillbilly said:

Here&#39;s the bad thing about ASP.NET MVC. Every little thing about it is bloggable mostly because every

# March 5, 2008 12:00 AM

dto said:

Pingback from  dto

# March 25, 2008 7:58 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add
Check out Devlicio.us!