Where’s the Real Reuse in ASP.NET MVC?

Just a quick note here.  I was playing around with ASP.NET MVC today, and I got to thinking, how does one encapsulate both behavior and markup (a la UserControls in WebForms) when using MVC?  Well, there’s a thing called a ViewUserControl that you can use in your ViewPages, but all that really does is encapsulate the markup and rendering.  You’d use them like this:

MyViewUserControl.ascx

And then you would call it from the ViewPage:

MyViewPage.aspx

If you use a typed ViewUserControl, you can feed the object to the RenderUserControl method as an additional parameter rather than going to the ViewData collection, but that’s not what gets to me.

The controller that renders MyViewPage.aspx is still responsible for retrieving all the data that MyViewUserControl.ascx uses. So, everywhere that I want to display that list of sponsors, I have to remember to write the code to go get it. That’s not really reuse, is it?

There was a comment on Rob Conery’s blog back in January that I ran across that suggested something like this:

That way, there can be one controller that’s responsible for pulling that Sponsor data from the data access layer. I’m not sure if this is possible; I’m not familiar enough with the way MVC works to know if a second (or third, or nth) controller can be created and called once the main controller has started rendering MyViewPage. From an end-user perspective, something like that would be great, since it would let us truly encapsulate every aspect of what that ViewUserControl is about. Here’s hoping!

7 thoughts on “Where’s the Real Reuse in ASP.NET MVC?

  1. David Mohundro

    Tried leaving this comment last night, but you switched blog engines on me!

    So, maybe I’m misunderstanding your question, but I guess I’m not seeing the lack of code reuse here. The controller wouldn’t be the code that accesses your data, it would be a repository, service, or other data access method and your controller would just delegate between data access and view. I would say that controllers will have very little actual code, because they’re really just there to handle the actual HTTP request and then decide who to talk to.

    I hope I’m not misunderstanding MVC here and I hope I’m not misunderstanding your question :) I would say that there is potential for the same data access to be called multiple times from multiple controllers, but that could be wrapped so it is essentially one call, like:

    IList myData = repository.GetMyData();

    Reply
  2. Brian Sullivan

    I don’t think you’re misunderstanding, maybe I’m expecting something unreasonable. My thought is that the controller ought to only be responsible for data explicitly accessed in the view it decides to render. So if I include a ViewUserControl named Foo in my view, I have to dig into Foo.ascx to see what data it needs so that I can make sure I go get it in the controller.

    What if I had five different ViewUserControls in a view? Five lines of code, multiplied by the number of views in which I want to use those common components = too many. And what happens if need to change the way I get the data for a particular user control? I have to go find every view that uses it, then find the controllers that render those views, and update the same line [i]n[/i] times. Why can’t I just have those five lines in five different files, little mini-controllers, and not have to repeat myself? Wouldn’t that be more dry?

    Reply
  3. David Mohundro

    Yeah, I follow now – Model View Presenter implementations do that a lot, where micro-presenters (is there a name for those?) only handle specific portions of the view.

    I wonder if you could get the same idea with your own controller classes that render out user controls instead of entire pages. I guess that’s what you’re suggesting though :)

    Reply
  4. Chad Myers

    FYI, from what I understand, partials, at least in the RubyOnRails context, are HTML fragments and not controller invocations. ASP.NET UserControls fit this bill nicely. The RenderUserControl stuff is a little clunky when it comes to passing the data, though.

    At Dovetail, to render a user control of type DovetailUserControl (just straight partial with some strong-typed data passed from the parent view), we do this:

    < %= this.RenderPartialFor(m=>m.Site.PrimaryAddress).Using();

    DisplayAddressControl is of type DovetailUserControl

    .

    We can also turn this into a repeater-like situation by doing something like this:

    < %= this.RenderPartialFor(m=>m.Solution.Resolutions).Using();

    The EditResolutionControl is DovetailUserControl. It’s called repeatedly for each Resolution object int he Resolutions collection.

    It’s working pretty well for us and everything is strongly-typed (no magic string/broken link funny-business).

    Reply
  5. JMorris

    This seems to be a severe limitation of MVC IMO. You can’t have ViewPage with multiple ViewUserControls that each call different actions on the controller? Seems kinda odd…the only way to do this is to have your action on the ViewPage return a hash of data or store it in ViewData. Imagine if you have two or more ViewUserControls that require pagination on a ViewPage? How would you handle this?

    Reply

Leave a Reply to Brian Cancel reply

Your email address will not be published. Required fields are marked *