July 15, 2008
MVC / IS FOR ME / ALL I SEE / IS MVC
Posted by scott at July 15, 2008 03:10 PM
Just got done deploying the very first bit of my very first MVC asp.net application. I got tired of waiting for the @#$% official framework to be released, so I didn't use it. But this is going to be a BIG project*, so I needed something. "Self," I says to myself, "it's just a design pattern. How hard can it be?"
Famous last words. Took me several hours to get my head wrapped around the asp.net page cycle so that my controllers weren't sending my models into update la-la land and locking up my views. Get thee back, stack overflow!
But now I've delivered the first chunk, and not only does it work it seems to work really well. Much better and easier to work with than the way I did it on my last project, with standard ASP.NET coding practices. I can unit test all the way up to implementing the view, and while it's far from trivial to build and test said view**, the benefits of building it this way mean de-bugging the view is at least straightforward and comparatively pain-free.
Oh, and one of the reasons why this seems pretty straightforward to me is I've been building MVC-like applications for years. My CF apps never posted back to the originating page. They always posted to a processor page, which updated the database, and then sent the user back to the screen. Sound familiar? I knew it would.
Hey, it's my blog, I'll write what I want to.
* Meeting management software for an annual convention with 2000+ attendees. Yeah, I know, there's dozens of them, but the only good ones are $$$, and even though you don't believe me this place really does have unique meeting requirements just not covered by anything else.
** One of the ways to tell you're doing it right, apparently, is testing the view becomes "trivial." To which I can only say, "WTF?!? Are you guys designing to 80-line monochrome?!? I got interaction, lots of it, to test!"
eMail this entry!
Worse than that - sounds like this app will be used by damn near everyone. And, as I've heard, it's one thing to code for smart users, but you can't ever outcode some of the dumb things people will do...
But, as long as you get the capability that your folks need and it's reliable, bulletproof, reasonably user-friendly, and it gets done for less than it'd cost to buy and adapt you get to play hero at work.
*checks out the linked Wikipedia article* So... when exactly would it be a good idea to let the view directly modify the model? Because I'm having trouble thinking of any that couldn't be turned into an script injection vector.
Ron: The beauty of the pattern is it makes views, the things people interact with, MUCH less trouble to implement. If I do it right, it will allow me to create views for each type of user, without requiring a re-write of any of the rest of the code.
T: The view never modifies the model. It doesn't really modify anything. There are different ways to implement it, but in mine when something happens in the view (a button is clicked, for example), the view calls a method in its controller, and simply hands off all the view-specific controls to that method*. The controller then translates this view-specific stuff like text boxes and radio buttons into primitives like strings and ints and bools, then hands them off to the model. The model then modifies itself (or doesn't, if it violates some rule).
Once the model is done, the CONTROLLER tells the view it's time to refresh, because the model has probably changed. The controller "knows about" the view and the model, and can control each. The view "knows about" the controller and the model, but only "talks" to the controller and "reads" the model. The model doesn't "know" about either of them, it simply provides methods and data for anyone that wants them.
See? Easy-peasy! :)
Any text box has the potential for script injection. In my implementation, the model "washes" the data before attempting to process it. If this results in "unprocessable" data, the model sets flags and errors to that effect, and the view displays these when it sees them on update.
* Which sometimes makes for some pretty impressive signatures. The "insert registration" call on that controller accepts some 32 arguments!
is this really a mature enough technology in .net? I saw a demo on it at DevConnections '08, and it seemed like an "oh by the way, we threw this together, isn't it neat, but not really useful yet." it took up less than half of one 1-hr session... I'd be worried that it won't get much support from MS in the future.
They haven't even come close to releasing the "official" version, so I rolled my own. It's just a design pattern... the whole point is it's not a bunch of widgets you use, it's a way of designing something.
There are DEFINITELY some challenges in implementing a classic MVC pattern in asp.net. The life cycle of the page gave me a few nasty bumps at first, and the way gridviews and objectDataSources work require a limited violation of the pattern, but other than that my implementation definitely works, and definitely seems to provide all the benefits as described.
using the MVC pattern that explicitly is actually kind of old-school. back in '00, I built a site using Oracle Application Service. there was code that built the page, and it posted-back to a different code with parsed whatever the user had done on the page, and then handed control to other code to create the next page for the user...
I think that what the big deal of ASP.net was is that you didn't have to do that explicitly any more, that you could handle the post-back in a more focused way, like win-apps do, on a per-control basis. and AJAX emphasizes that even more.
while coding using the MVC pattern gives you a greater ability to test against the user interaction, you lose some of the flexibility and ease of coding that you currently have in standard ASP.net with AJAX.
a choice to make. I don't think it will gain that much market-share, though.
I'm just going by the Wikipedia article, which shows the model being directly modified by the view (and the view being indirectly modified by the model).
If it's a typo, then someone needs to fix it.
I think the pattern itself might go back to the early 80s, maybe even the 70s (too lazy to look it up).
I was inadvertently doing MVC just like this back in 97 with cold fusion.
The ease I lose in basic coding, on a project this big and complex, IMO is more than outweighed by the confidence I get from all the automated testing and the flexibility provided by the pattern itself.
I tried using regular (well, how I understand regular) asp.net practices on my last medium-complexity project, and it ended up being a nightmare to debug. I was probably doing it wrong, I usually do. *shrug*
So far, the only thing I *know* I've lost are the validator controls that come in VS. Since I don't particularly like them*, it's not much of a loss for me. :)
T: It's very possible I'm doing it wrong. In my implementation, it's the controller that modifies the model, not the view.
* In the same way those wackamole fundies don't particularly like gay people, sort of thing.