Hugoware

The product of a web developer with a little too much caffeine

WebControls In MVC… again…

with 11 comments

I’m a big fan of MVC so far but there are certainly parts that I don’t like. For example, who is responsible for logical changes to a HTML markup in a view? The Controller? The Model? Personally, I don’t think either of them should which leaves the View to pick up the slack.

But the problem is that I end up with a bunch of crud in my View — which to me looks a lot like a Classic ASP website.

It doesn’t take a lot — Just look at a fairly reasonable example…

<div class="<% if (user.IsAdmin) { %>admin-icon<% } else if (user.IsEditor) { %>editor-icon<% } else { %>user-icon<% } %>" >
<!--snip...-->

I realize that you always have access to RenderPartial and you can also start using a templating engine but I still feel this is something that a WebControl could handle perfectly.

Using A WebControl For Markup

Now if your first thought was “You can’t do anything to WebControls in the Render stage of the page lifecycle” then you’re absolutely right. However, it is possible to gain access to earlier than that and use it with models.

This next bit of code is pretty daunting… I’d recommend you send any children out of the room and shield your eyes…

<!-- Old Sample...
<mvc:MyControl SomeProperty='<% #DataBinder.GetPropertyValue(this.Model, "TheProperty") %>' runat="server" />-->

<!-- As it turns out, you can simply call it like... -->
<mvc:MyControl SomeProperty="<% #this.Model.TheProperty %>" runat="server" />

And that is about it! Really!

The second step requires that you call the DataBind function for the page… but you can’t call it as part of the render (otherwise it is too late). You could use a server side script tag at the top of your page, but I recommend you just create your own ViewPage class that takes care of it for you. Below is the class that use in later examples. Again, there is an insane amount of code so be warned…

/// <summary>
/// ViewPage with Model access for WebControls
/// </summary>
public class MyControl : UserControl {

    //some point the the control lifetime call DataBind
    public override void OnLoad(object sender, EventArgs e) {
        this.DataBind();
    }

}

How About A Real Example Then?

So this sounds interesting, but how could it really be used? I’ve include a Visual Studio solution file with some examples that go over possible ways to use WebControls in your MVC applications.

  • Twitter Feed: Writes all of the logic and rendering of a simple Twitter feed. Uses the BoundedViewPage to attach a user name to the Property of the control. Also allows normal access (assignment from a string) so you could reuse the code anywhere.
  • Calendar: Example that uses a Calendar control and a Grid View to create a a simple page of content but uses binding to the Model to get information for all of the controls.
  • Task List: Simple task list that shows how you can use a UserControl with button click events to update the Model and then show the results on the page.
  • Crash Example: Using RenderPartial on a page that has a server form does not work correctly. However, if your WebControl doesn’t use a server form (which is better anyways) then you can use all MVC features without a problem (as far as I know, that is)

Of course, I’m sure a lot of people will be against this idea but I think it is worth exploring. If you think about all of the new features that ASP.NET 4 is going to introduce (especially better control over the client side markup) then this might end up being a perfect combination!

Source Code

WebFormAccess.zip (Solution Files)

Previous Posts On WebControls In MVC

Here are some earlier posts messing around with this same concept — Admittedly, these are geared to using WebControls and the entire WebForms model.

Written by hugoware

January 31, 2010 at 10:54 pm

11 Responses

Subscribe to comments with RSS.

  1. Hugo, it’s time to let go of controls man! For the user icon, write an HTML helper so you could do

    Between partials and HTML helpers I don’t see any need for these wacky controls. At the risk of sounding like a jerk, if you really want controls, just stick with Webforms. I’m really not seeing any benefit here. Just because you can doesn’t mean you should…

    John Sheehan

    February 1, 2010 at 12:32 am

    • I can think of one. When you’re trying to build a new project but the bloke in charge wants you to use MVC but also use the nice ajax web controls he’s already got and doesn’t realise when are where each technology should be used * 🙂

      * same bloke. That’ll be me.

      David Buckle

      March 27, 2010 at 11:15 am

  2. My html was stripped: my html helper example was Html.UserIcon(Model.User)

    John Sheehan

    February 1, 2010 at 12:34 am

    • Yeah, I peeked in to see if I could fix it up for you but it was completely gone.

      I’m not suggesting we get back into full logic with code behinds (even though you can do it and it is pretty interesting to see it in action).

      But with my examples, using a code behind to manage visibility, styles or whatever looks a whole lot better than a myriad of <% and %> tags all mashed around the page or inside of an attribute on a tag.

      I’m not opposed to templating engines at all (like Spark) but I do think that a the new features in ASP.NET 4 with a dash of MVC WebControls could be a powerful combination.

      Anyways, I always appreciate your feedback – Thanks for taking the time to comment

      webdev_hb

      February 1, 2010 at 12:42 am

      • I guess I’m a little confused at your willingness to write all this extra hacky code to get these controls to work instead of writing proper MVC html helpers. Is it a familiarity thing?

        You mention a couple times there’s a benefit to doing it this way. Could you expand on that? What practical benefit is there to using these sorts of controls in an MVC project?

        John Sheehan

        February 1, 2010 at 1:05 am

      • Is a call to DataBind and using the DataBinder class really that hacky? Especially compared to my earlier blog posts on this same topic 😉

        As far as benefits – Where does MVC code work? In an MVC project, right? But what about WebForm code? Since we’re using existing ASP.NET then WebForm code should work anywhere (it is, after all, just HTML)

        In my uploaded solution file I have an example of a Twitter feed that can be dropped into any ASP.NET project that it wants to be in. Both WebForms users from their code behind and MVC users from their Model can assign to the properties and benefit from the control. Encapsulated code all available in a nice neat little package (good thing).

        If I wanted to create a reusable block of code for MVC, I would need a Controller to download the Twitter stream, Models to parse and prepare the content and a View to actually show the output. Of course, everything created would need to be merged into the project (Controller action, Twitter model and any View/HtmlHelpers created)

        For the record, I’m not planning to binding datagrids (or really any built-in WebForm control for that matter) inside of MVC projects. But If you write a WebControl that emits good, clean markup that avoids a hard to read server tag nightmare, is it really bad practice?

        Alternatively, I remember reading the @shanselman blog post where he polled the community to see the adoption of different Microsoft technologies. Admittedly, the stated that the MVC usage might be slighly skewed, but you can see from his poll that there are a lot of WebForms developers that just aren’t ready to let go. Why not let them ease into MVC with a couple familiar features along the way? Heck, they might even be able to reuse some of their code (which I know is a very large hurdle for some)

        Anyways, I’m rambling again – I of course don’t expect to convince you to convert but it certainly is fun trying 😉

        webdev_hb

        February 1, 2010 at 8:09 am

  3. […] to VoteWebControls In MVC… again… (1/31/2010)Sunday, January 31, 2010 from webdev_hbI’m a big fan of MVC so far but there are certainly parts […]

  4. i downloaded your source code WebFormAccess.zip. it runs fine but i don’t see any post back is working? No button click triggers server side events in webforms?

    hassan

    June 24, 2010 at 8:30 am

    • Hmm… Are you using MVC2? I’m not so sure this works the same as it did before.

      hugoware

      June 24, 2010 at 10:02 pm

      • Yes! i am using MVC2. I ran your solution as it is…but i couldn’t get any postback. In fact, the form submits but page events don’t raise.

        Is it because of MVC2?

        hassan

        July 2, 2010 at 3:17 am

      • My previous code quit working with MVC2 (https://somewebguy.wordpress.com/2010/04/06/adding-stylesheets-scripts-in-asp-net-mvc2/) – I’m actually surprised you aren’t getting exception messages.

        I’ve been experimenting lately with overwriting the ViewContext.Writer property but I’m not sure if it will fix this problem in particular… As I find out more I’ll post it here

        hugoware

        July 2, 2010 at 1:48 pm


Leave a comment