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

Archive for August 17th, 2009

Using WebControls In ASP.NET MVC Views – Part 4

with 2 comments

Check out my newest blog post about using WebControls inside of MVC (source code included)🙂

WebControls In MVC Series

Disclaimer : This post is a rough overview how the MvcWebForms class works. If you don’t really care then you probably won’t want to finish reading this 🙂

In part 3 of this series we finally got to use some code that actually allowed us to use the entire post back process from an inline call with MVC. The next few parts of the series dives into how the code actually works — and hopefully discovers a few bugs and optimizations along the way!

For part 4 we’re going to focus on this small segment of code.

<% this.Html.WebForm((build) => { %>
<label for="name" >Name</label>
<% build.RenderControl(new TextBox() { id = "name" }); %>
<% }); %>

The WebForm Extension Method

Line 1: <% this.Html.WebForm((build) => { %>

The first step to render a WebForm is to call the HtmlHelper method WebForm. This method might look a little odd since it expects a delegate but it is required so that we can continue to use markup along side our WebControls, which we explain a bit more in a moment.

The delegate accepts a single parameter which is the MvcWebForm. You can think of this as the Page.Form you’re used to having access to. You can make changes to the postback target, attributes, content type, etc. The MvcWebForm is also where you provide the WebControls you want to render using .RenderControl(). There are several overloads to this method so you might want to poke around to see what kinds of options you have.

The delegate you provide isn’t executed immediately, in fact the Form element is created first and then a few content markers are added to the code. After all of the setup has taken place the code is the delegate you provided is rendered onto the page.

You might think that the rest of the code simply renders the output inline and then returns to executing the ViewPage code, but interestingly enough, the controls you created aren’t rendered to the page yet but instead placed into a queue.

Queuing Controls For Rendering

Line 3: <% build.RenderControl(new TextBox() { id = "name" }); %>

In order to render the WebControls correctly we need a context in which they can all be aware of one another. With WebForms, each stage in the Page Life Cycle gives you time to make changes to the document before the content is rendered, but in MVC you’re already in the Render stage — you can’t make changes to the content you just finished rendering! Clearly, we can’t render these controls inline.

Each time we call .RenderControl() we are actually creating a content marker for that control and then moving it to a queue. After the control is rendered the content is inserted back into the correct marker along with any scripts or stylesheets.

You might be wondering how we could do something like that, since we’re in the middle of the Render() call and that part of the page has already passed by. Recently, I had written some code to help me add stylesheets to the header of my MVC page from inline code — To say the least, it ended coming up very handy in this project.

Completing The WebForm Request

Line 4: <% }); %>

After the delegate has finished creating the content the remaining code finishes the rendering process and closes up the WebForm we are creating. After that point it is time to actually render the WebControls to display.

After the delegate has finished the code combines all of the controls into a dynamically loaded .ASPX page and then processes it. Once finished we end up with a string of the rendered HTML output which can be parsed into a XDocument! Each control is then matched up and the rendered HTML is inserted into the matching content marker! If any scripts or stylesheets are created then they are rendered into the top of the WebForm.

Really, There Is A Lot More

This is a rough overview of how the process works but I’ll get into detail more on each section through the rest of the series.

Written by hugoware

August 17, 2009 at 2:42 am