Converting from Webforms view engine to Razor–Some Tips

Recently, I have had to perform a lot of conversion in an MVC application from using the webforms view engine to the Razor view engine.

I say “had to” but we didn’t really have to, more wanted to. We wanted the cleaner syntax that razor allows. Since we were going to embark on a bunch of new features involving new pages, we wanted to do this conversion earlier rather than later to prevent excessive rework.

This post simply summarises most of the issues and tips that were experienced along the way and how we overcame them, so that others can get a clear picture of what is involved should they embark on such an undertaking, and be prepared for any issues.

Preparation

First off, there are some things you should do prior to starting the conversion to make the process as smooth as possible, and to allow easy resolution of any issues.

  • Take a copy of your entire source tree and keep it separate to allow for comparison along the way. If you are using HG or GIT, clone your repository to another location. Sure you could look at source control history if you wanted, but its easier to have this code at hand to do side by side comparisons.More importantly though, you can run the backup version to compare HTML output to make sure your conversions are good.
  • In your solution, turn on MVC compiled views. This will tell the compiler to compile your views and you will catch any errors whenever you compile. Very handy and saves sometime. Unfortunately, it does add some time to the build process. If you have a lot of views, this could be lengthy, so you may want to disable this after the conversion is complete. To enable compiled views:
      • Right click on your project in solution explorer, and select Unload Project.
      • One its unloaded, right click on it again and select ‘Edit Project. The project XML will load in the editor window.
      • Locate the following
<MvcBuildViews>false</MvcBuildViews>

and change it to

<MvcBuildViews>true</MvcBuildViews>
      • Save the file. Then right click on the project again and select ‘Reload Project’
      • Now when you compile, your views will also be compiled.
  • Download the aspx2razor conversion tool from Telerik which does a reasonable job of converting your ASPX views into razor views. It probably wont do it all for you,but it removes a good deal of work.

Performing the actual conversion

This is the easy part. Simply run the conversion tool over your project. You can do this by running the tool against your base views directory and have it recursively convert all files it founds in all directories to their razor counterparts. Something like this:

aspx2razor.exe c:\MyProject\MyViews\*.cshtml MyOutputDirectory -r

You will then need to copy the files from the output directory into your solution and ensure they are included in the project. Make sure you delete all the existing ASPX files as having both of these file types present can cause problems.

So that’s it. Job done right?

Testing and Fixing

Now the fun begins. The conversion tool works reasonably well, but it has its problems. Here are some of the issues you will find.

  • The conversion tool does not support master pages, so don’t expect them to be converted. Roll up your sleeves and do those manually. Even though the tool does not support master pages, it will blindly convert anything you tell it to so it will attempt to convert a master page if one exists in the set of input files. Don’t be tempted to use a partially converted master page if there is one as it will usually not convert properly, putting in an incorrect ‘@inherits’ directive which just causes more confusion. Start from scratch and do the master pages manually.
  • Sometimes the conversion tool completely misses the server side tags, particularly when embedded in script tags like this:
<script type="text/javascript" language="javascript" src="<%: Url.Content("~/Content/Scripts/jQuery/jshashtable.js") %>"></script>
  • Embedded server tags can get completely messed up when converting to razor. As an example, the following snippet:
class="item <%: isParentDate ? "" : "child-date " %>
<%: item.IsReconciled ? "reconciled " : "" %>">

gets converted to the following razor equivalent:

class="item @isParentDate ? "" : "child-date "@item.IsReconciled ? "reconciled " : """>

which is obviously incorrect and results in simple text being output to the HTML, not the expected class names. Ideally, this should be refactored into amore explicit code block, something like this:

@{ 
  var divClass = string.Format("item {0}{1}", isParentDate ? string.Empty : "child-date ", item.IsReconciled ? "reconciled " : "");
}
class="@divClass"
  • “Tight” concatenation of server tags like this:
<input type="hidden" id="itemAmount<%: Model.BankFeed.Id %>" />

get converted to this:

<input type="hidden" id="itemAmount@Model.BankFeed.Id" />

which is not right and just renders the text. Again, something more explicit is required such as:

@{ 
  var controlId = string.Format("itemAmount{0}", Model.Id);
}
    <input type="hidden" id="@controlId" />
  • One last tip. Use the “original” copy of your site and run it up in a browser, do the same with the converted site. For each view that is converted, it is worth doing a “source view” of original and converted page from the browser to ensure you are getting the same output. This is particularly important for scripts and CSS.

That is about it for most of the issues I came across. You will no doubt experience some variations from the examples above, but the set of issues presented here should at least allow you to be prepared for what the actual conversion effort is going to be.

Hopefully, this article helps you to efficiently convert your projects into the wonderful world of razor Smile

17 Comments

  • Great post! A lot of people run into some of the issues you point out (including myself) so people need to send you a check for the time/money you just saved them. :-)

    One other tool I've found useful for migrating the project and updating web.config can be found here:

    http://blogs.msdn.com/b/marcinon/archive/2011/01/13/mvc-3-project-upgrade-tool.aspx

    Dan

  • I'm not sure of using the tool to do it Glavs. We had a similar situation of converting .aspx/ascx pages to cshtml. We did it manually and in the end most of the developers actually learned the Razor syntax. (Copy n' Paste hasn't taught us much now has it!).

  • Dan,

    Thx for the kind comments and extra link.

    Arun,
    You certainly don't have to use a tool and doing it manually will let you learn a lot along the way, but it is not very time/cost effective way of doing it if you have a lot of views and a smaller team. As already mentioned, there is always a manual element to it anyway.
    Thanks for the comments.

  • I'm with Arun; manually converting really gets you into the language, and thankfully you can have both view engines in place, so you don't have to do everything at once. (Migrating as you work within files makes sense.)

  • While the article is usefull. The idea is useless. Personally, I don't really see the reason to convert web forms to razor, especially for established web sites...

  • igorb,

    Regardless of whether you believe its useless, people do want to convert to razor for a variety of reasons. Some of which will be more apparent as time goes on.

  • I'm not sure what is meant by "cleaner syntax". I've done some MVC stuff recently and saw no difference between dynamically writing HTML and content via literal controls in Web Forms vs. the MVC approach. In fact, there ended up being twice as much code the MVC way... Not sure that's cleaner.... it's definitely not easier nor was there any performance gains on a recent project I converted. I've abandoned MVC until there is some sort of benefit from using it.

  • Actually people want to test with razor. and how it will be better with razor. Reason is only testing.

  • Nick,

    I personally find it cleaner, as do many others. I has less markup transitions than many other markup transitions, webforms in particular. Writing HTML content via literal controls is IMHO not really a good idea in general as it negates the benefit of markup itself.
    As to abandoning MVC, each to his own. MVC is a good framework but not for everyone. In which case there is nothing wrong sticking to webforms.

  • rudraksha,

    While people certainly will want to trial with Razor, it (I assume this article and its techniques) is not only for testing. Many people want razor and will convert their apps to it. This article is for them. For those that dont, then, quite simply, don't. This article is not for them.

  • Great Post ! Tks a lot !

  • thank youuuuuuuuuuuuuuuuuuuuuuuuuu
    very helpfull

  • Didn't work for me:
    I typed:

    aspx2razor.exe C:\MySolution\Views\*.cshtml C:\T\Output with Razor\OutPut -r

    It just returns 0 files converted.

  • I am also Getting This text "0 Files converted" whats wrong here in this command "aspx2razor.exe C:\Projects\Zamzam\Source\cmg.web\views myExProject -r"

  • Would Some body
    please let Me know that Whats problem in my conversion

  • cOuld Some body PLease Tell where Is The Problem

  • Guys, you need to specify a wildcard after the path such as:
    aspx2razor.exe "C:\Projects\Zamzam\Source\cmg.web\views\*.aspx" myExProject -r

    That is, dont just specify the directory, you must also add *.* or *.ascx.

Comments have been disabled for this content.