9

I think many of us used to face the same question: what's the best practice to port existing web forms App to MVC. The situation for me is that we'll support both web forms and MVC at the same time. It means, we create new features in MVC, while maintaining legacy pages in web forms, and they're all in a same project.

The point is: we want to keep the DRY (do not repeat yourself) principle and reduce duplicate code as much as possible. The ASPX page is not a problem as we only create new features in MVC, but there're still some shared components we want to re-use the both new / legacy pages:

  • Master page
  • UserControl

The question here is: Is that possible to create a common master page / usercontrol that could be used for both web forms and MVC? I know that ViewMasterPage inherits from MasterPage and ViewUserControl inherits from UserControl, so it's maybe OK to let both web forms and MVC ASPX page refer to the MVC version. I did some testing and found sometimes it generates errors during the rendering of usercontrols.

Any idea / experience you can share with me? Very appreciate to it.


Background:

This UI project has been created for years and there're 20+ people working on that. Before I start the common master page trial, there're about 50+ web forms pages and only one MVC page. We create new features on MVC, but the old pages keep remaining in web forms.

This situation will keep for a long time, probably because this's a business-driven company so new features are always in a higher priority. This means we need to support both at the same time.

tshao
  • 1,127
  • 2
  • 8
  • 23

4 Answers4

6

There are several integration problems using ASP.NET MVC master page with web forms pages and user controls. Since the execution pipelines of the two frameworks are not exactly the same it is normal to have some problems.

One of the things I've faced is that web forms uses single interface pattern (it has one <form> tag with runat="server" on the page). In your master page or pages using it you'll have to create this tag yourself if you want to use server controls. Note that this will work for read-only controls. If you need post-back & event handling you'll probably face more problems with event handling and event validation.

Also one trick is to create html helpers that render existing controls to string. You can check this out for more info http://www.abadjimarinov.net/blog/2009/10/29/HowToRenderAspdotNETControlToString.xhtml This is also a partial solution as it will not work with most user controls.

It will be helpful to provide some code or error messages so I can give you more concrete answers. At this level I can only say that the two frameworks are compatible and you can integrate them but this will not be painless and will require some changes in the existing code.

Robert Koritnik
  • 103,639
  • 52
  • 277
  • 404
Branislav Abadjimarinov
  • 5,101
  • 3
  • 35
  • 44
  • Thanks Branislav! I'm about to rest and read your reply later. Appreciate it very much. :) – tshao Jan 03 '11 at 15:29
  • We don't use postback at all for server controls. One problem for me is that we usually use a registered tag for user control in web forms, e.g. ..., while using Html.RenderPartial() in MVC. If I need to include a user control in master page which supposed to support both web forms and MVC. How should I write it? – tshao Jan 03 '11 at 15:38
  • In MVC while using web forms view engine you can still register and use user controls with tags. In your case I'll suggest using the approach described in this article - http://blog.wekeroad.com/2008/01/07/aspnet-mvc-using-usercontrols-usefully – Branislav Abadjimarinov Jan 03 '11 at 18:04
  • @tshao: You can still use the `@Register` server declaration to register custom controls. That's possible since MVC uses the same rendering engine as webforms do. Hence you can use user/custom web controls. If you'd use Spark view engine instead you wouldn't be able to use them any more because it's completely suited to Asp.net MVC. – Robert Koritnik Jan 04 '11 at 07:10
  • @tshao: Razor not Spark... My bad. – Robert Koritnik Jan 04 '11 at 07:17
3

Let me use an analogy

This will sound harsh but will make it easier for me to pass the idea across. Exaggeration helps sometimes because it emphasizes certain things that need to be understood.

Ok. We're using bicycles to get from A to B at the moment. We're considering buying a car but we want to make transition from one to the other as painful as possible. Consider the fact that we enhanced our bike so it uses custom pedals etc. Is it possible that we use these pedals and other enhancements with the new car we're considering?

Essentially it's possible. But without making a huge mess out of it it is definitely not advisable.

Suggested transition is to change pages one by one to use the new technology (new ones of course in the new technology) and not to introduce some MVC functionality to a webforms page. Either MVC or WebForms for a particular user process. Majority of non-UI code can be reused (business services, data access layer code, data/domain model when applicable). But if you're cramming all the code in your code-behinds... Well bad luck for you. If you haven't separated your code you will more or less be repeating code. Unfortunately that's not Asp.net MVC's fault. It's your bad design without SoC.

Don't combine/mix/blend two UI technologies if you're not suicidal. You can go from A->B using either bike or car, but not both at the same time. This means you can have WebForms part of your application and MVC part of it, but not likely on the same page. And this is only possible if you use Web applications not Web sites. Asp.net MVC can't work as a Web site (on demand partial per page compilation).

Re-usability related to my analogy

Bike and car are two UI technologies. What you do or the purpose of you taking the route from A->B is not important. That's business logic. If you're delivering newspapers that's not related to transport. So you can see that other layers can be reused.

Asp.net WebForms vs. MVC

Asp.net WebForms
Server-side controls (web/user) use the event pipeline execution model. Hence they (unless completely presentational nature) have server side events that some code subscribes to. Platform is completely state-full and everything executes in a manner that abstracts the HTTP completely away. Everything looks like you'd be running a desktop application.

Controls usually encapsulate presentation, code (as in server-side and client side script) and style (as in CSS). That's why it's a lot harder to have SoC using WebForms.

Asp.net MVC
This platforms is completely suited for the stateless nature of the HTTP protocol. Every request is completely stateless (unless you store some state data in persistent medium - Session, DB, etc.). There's nothing like an event model. It's basically just presentation of data/information that is able to transfer data to the server (either as GET, POST, DELETE, PUT...). Server side doesn't have any events. It's only able to read that data and act upon it. And return some result (HTML, Script, JSON, ...). No events. No state. No complex abstractions.

Asp.net MVC abstracts away some common scenarios that are related to data. Like automatic conversion to complex object instances and data validation. Everything else is gone.

Asp.net MVC using WebForms
In case you would like to use server-side controls in an MVC application you would be able to put them in your ASPX/ASCX, but they would only be used as pure presentation. You'd provide some data to render. And that's pretty much it. Postbacks wouldn't even work (unless you'd put a submit button on it), because there's no __doPostback client side functionality that would make a POST request to the server. So if there's any server side code that these controls have (even when they didn't initiate a postback) and are related to it's state-full lifetime after they've been loaded, you can say goodbye to them. More or less.

Other than that, you can read a lot about differences between Asp.net WebForms and Asp.net MVC on the internet.

Robert Koritnik
  • 103,639
  • 52
  • 277
  • 404
  • Thanks Robert! Actually I can't agree more with you. I'd like to put some background so we know better why it's a problem :) – tshao Jan 04 '11 at 01:49
  • @tshao: You're right. I've added some information to clarify the problem a little. – Robert Koritnik Jan 04 '11 at 06:56
  • @tshao: I've added quite a few additional facts you may be interested so I suggest you re-read my answer completely. – Robert Koritnik Jan 04 '11 at 07:15
  • Actually I'm not new to MVC and concept of SoC, and the existing pages don't rely on postback, which makes the migration much easier. The existing design is generally OK so it's not that much repeated code in two master pages. But why do we need two if we can do it in only one? – tshao Jan 04 '11 at 15:15
  • @tshao: Well basically if your master pages are pure layout you can easily use the same file. For instance when I integrated MVC into Sharepoint 2010 I used existing master page to render my views. Worked without any bigger problem even though there were many server side controls on the master. But they don't have any postback related functionality. Thanks for that. – Robert Koritnik Jan 04 '11 at 15:50
  • I just want to point out that this: "Everything looks like you'd be running a desktop application." is probably the main reason I considered moving away from Webforms.. the «looks like» = a huge truck of garbage injected into your HTML just to give you the impression (yes, you read it well..the impression!) that you're running in a stateful platform. – António Sérgio Simões Mar 31 '14 at 20:00
2

You can do a certain amount of integration between the 2, but you end up with something more complex & less satisfactory from either approach. A comprise in other words.

I've had this same problem in the past & server side includes worked for me. Old school I know & not something I'd generally recommend. But we don't work in an ideal world.

Simon Halsey
  • 5,459
  • 1
  • 21
  • 32
2

Sharing MasterPages: see this thread.

User Controls:

This is one of the banes of my existence with MVC; in MVC2 and previous revs, there's no direct equivalent to webforms user controls. A sort-of workaround is creating HtmlHelpers - (effectively extension methods to the Html object available in views that return HTML), but that means you'll have to render your HTML in code. Teh suck.

With MVC3 and the Razor view engine, a new class of Html Helpers is available that provides most of the benefits of user controls, including the ability to place them in separate assemblies (and therefore can be used in multiple projects). I'll see if I can dig up an example link, but Scott Guthrie's blog had an example in one of his recent MVC3/Razor posts.

Community
  • 1
  • 1
3Dave
  • 28,657
  • 18
  • 88
  • 151