Running ASP.NET MVC 3 on Azure

If you have successfully installed an app running MVC 2 on Azure, and then try to upgrade it to MVC 3, you might run into some troubles.

What might help is to ensure that you have also deployed the new assemblies. MVC 2 is part of .NET 4.0, and its assemblies are included in the standard Azure image, but the new ones aren’t. You have to deploy them yourself.

They won’t get deployed by default because they are in the GAC. You have to make sure that “Copy Local” is selected for the relevant MVC assemblies.

The instructions on how to upgrade and MVC 2 project to MVC 3 are in the release notes, and involve replacing some of the old references with the new ones. But those assemblies have dependencies that aren’t copied.

The assemblies I needed to run an MVC 3 project (using Razor) on Azure are:

  • Microsoft.Web.Infrastructure
  • System.Web.Mvc
  • System.Web.Razor
  • System.Web.WebPages
  • System.Web.WebPages.Deployment
  • System.Web.WebPages.Razor

I’m not 100% I needed System.Web.WebPages.Razor, but it seemed like a good one to have.

I did not need System.Web.WebPages.Administration. If you include that, you need to include NuGet as well.

I don’t actually know what any of those assemblies specifically do (I don’t know what the WebPages or Microsoft.Web.Infrastructure assemblies are for), but this is what I’ve needed to deploy to get it to work.

AJAX history with ASP.NET AJAX 1.0

If you are still using the original ASP.NET AJAX 1.0 release, you may be looking for a way to use .NET 3.5 SP1′s “history” feature of the ScriptManager control.

A while back, Nikhil Kothari wrote a component called UpdateHistory, which looks like what was integrated into 3.5 SP1. It certainly solved my problem.

Combine it with HttpUtility.ParseQueryString and you’re onto a winner!

Declarative data binding on User Controls

I had this problem a few years ago and figured that there was no good solution, but I am older and wiser now so figured it’s time look for a better solution.

I have a GridView, and inside the ItemTemplate I call one of my own UserControls:


<asp:GridView ID="grdMessages" runat="server" ... >
  ...
  <ItemTemplate>
    <uc1:EmailAddress ID="EmailAddress1" runat="server" 

      DataSource='<%# (MailAddress)Eval("FromAddress") %>' />
  </ItemTemplate>
  ...
</asp:GridView>

But the DataSource property of the EmailAddress user control is never set. If I have a plain <%# Eval("FromAddress") %> right next to the <uc1:EmailAddress /> tag, the literal evaluates properly. The user control doesn’t.

My original solution was to just set the value of the user control’s properties in the code behind class. But I shouldn’t have to do that. (It’s also a bit annoying to do that because I’d have to handle the GridView’s DataBinding event and then find the control and update it.)

There’s got to be a better way!

I overrode the user control’s DataBind and DataBindChildren methods, to see if they were being called. They were.

So then I tried it with a Literal control, setting the Text property. Probably the simplest .NET Web Control there is. Obviously that worked, because that’s how data binding is supposed to work. So there must be something that the Literal control does that mine doesn’t. Time to pull out Reflector!

The Literal.Text property has an attribute called Bindable. Could this be it? It makes sense. Its full name is System.ComponentModel.Bindable. Does it work? Nope.

Hang on a tick… the DataSource property is being set now. So what is my problem? The code that’s doing the work is in the Load event handler. But the DataSource property is being set after Load. So I’ve moved that code to PreRender and…

It works!

So what have we learnt?

To make a UserControl’s property bindable, you must use the [Bindable] attribute. And those properties will not get bound until after Load, so don’t put code that relies on your bound properties in the Load event handler!

ObjectDataSource.SelectCountMethod wants an int

I have been working with the GridView ASP.NET control today, bound to an ObjectDataSource. This is to do with my experiment with DBMail that I mentioned the other day. It wasn’t working. I couldn’t find a solution on the net. By chance, I changed this:

    class DatabaseSource
    {
        long _messageCount = 0;

        public List<Message> GetMessages(long startRow, int pageSize)
        {
            Database db = new Database();
            List<Message> messages = db.GetMessages( startRow, pageSize,


               out _messageCount);

            return messages;
        }

        public long GetMessageCount()
        {
            return _messageCount;
        }
    }

into this:

    class DatabaseSource
    {
        long _messageCount = 0;

        public List<Message> GetMessages(long startRow, int pageSize)
        {
            Database db = new Database();
            List<Message> messages = db.GetMessages( startRow, pageSize,


               out _messageCount);

            return messages;
        }

        public int GetMessageCount()
        {
            return Convert.ToInt32(_messageCount);
        }
    }

Notice the difference?

To get the ObjectDataSource to work, the SelectCountMethod has to return an 32-bit integer (System.Int32). It failed (without an error message) when it was provided with a long or 64-bit integer (System.Int64).

It turns out it’s written in the documentation in black and white:

Type: System.String

A string that represents the name of the method or function that the ObjectDataSource uses to retrieve a row count. The method must return an integer (Int32). The default is an empty string ("").

Who would have thought?

Hopefully this will save someone who is running into the same problem. (That’s assuming that this will pop up in their search results when they search for ObjectDataSource and GridView paging not working!)