fooberry

Sweetness without context.

Sharing master pages between WebForms and MVC

March 29th 2010

Lets face it. Everyone loves MVC. At least all the web purists love it. Its clean, straight forward, and very testable. But lets also face it. We have a huge investment in WebForms. I mean up until now, 100% of the stuff we built was WebForms, include 100% of the master pages.

These pages govern how  the entire site looks and a wee bit of its functionality.

a

It would be a real shame if we had to start being less DRY and copy all that markup, in potentially many files, to new, MVC master pages. Luckily, you dont.

Let me stop right there. Technically, no, you dont. Mvcs ViewMasterPage (VMP) inherits from MasterPage (MP), so you can just tell your VMP to use the MP you want and it will work, unless you have the single line I hate more than any other lines in your MP.

<form id=Form1 runat=server>

 

So this single line blows the possibility of using the master page as a VMP out of the water. No problem right, include that in a nested MP and put that runat=server around the content place holder, right?

a_3

Thats nice and all, but all those other bit out side of the WebForms specific master page needs to be inside that stupid form.

image

Uh oh! No way around that one! Either move the run at server form outside or convert those controls. Id vote for convert the controls.

OK, so how about just use partial views and HtmlHelpers. That sounds like a good idea. Heres another problem.

<%= Html.MyMenu() %>

 

System.Web.UI.MasterPage does not have a HtmlHelper attribute where we get all those nice HtmlHelper Extensions. What about just creating one and using it?

<%= new HtmlHelper(null,null).MyMenu() %>

 

Great! That compiles, but dont get too excited. It doesnt run. We cant just pass null into HtmlHelper. We can new up the first parameter and create our own custom implementation of the second and it does work.

<%= new HtmlHelper(new ViewContext(), new FakeViewDataContainer).MyMenu() %>

 

That looks nasty too, but since that is my own customer helper extension, when not just call into that directly.

<%= MyMenuHelper.MyMenu(null) %>

 

Thats better, and since we arent using the HtmlHelper at all, we can clean up the syntax just a bit.

<%= MyMenuHelper.CreateMenu() %>

 

I can live with that, but if we ever need to do anything complicated that requires view data or other information to be passed along, were in a nasty situation. This works for us for now, so were going to ride this idea for a little longer and see how it goes.

Eventually all those WebForms pages will be moved over to MVC and this wont be an issue. Well have only the MVC master page and everything will be simple.

blog comments powered by Disqus