Search code examples
.netasp.net-mvcrunatserver

What is the status of runat="server" tags in ASP.NET MVC?


Some texts on ASP.NET MVC state that "there are no runat server tags", even this MSDN article says this, when, right above that statement there is a code example with a runat server tag in the HEAD element:

And on StackOverflow conversations I read

"The fact that you want to use "runat=server" controls means that you should be doing a traditional ASP.NET app.

And of course in the Site.Master page there are runat server attributes in the ContentPlaceHolders.

The only thing I see absent from ASP.NET MVC in terms of runat server is the ubiquitous FORM runat="server" tag on each .aspx page/view.

But what about the rest of the runat server tags in ASP.NET MVC, what do people mean when they say that ASP.NET MVC does not have these?


Solution

  • If you use a runat="server" tag on ANY element, such as a DIV it will render that code as a separate method in the compiled page.

    If you're converting 'legacy' code its a good idea to remove all runat tags right up front otherwise you end up in a situation where code like the following gives you an error.

    <% foreach (var cat in cats) { %>
        <div runat="server">
             <span class="name"> <%= cat.name %> </span> is a
             <span class="breed"> <%= cat.breed %> </span>
        </div>
     <% } %>
    

    This code will fail telling you some craziness about 'cat' being out of scope. Eventually when you look at the full generated code you'll see that the <div> has been generated as its whole own method - which is of course a different scope with no cats in sight.

    Back for a second to the default template for an MVC application:

    You'll see the current template gives you this for the head :

    <head runat="server">
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
        <title><%= Html.Encode(ViewData["Title"]) %></title>
        <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
    </head>
    

    This left me wondering -- if we're using <%= syntax to write the title directly into the title tag - then why would we need to make it runat?

    It turns out as I suspected that the codebehind for head looks for an existing value inside the title tag (which would have been output here by <%= Html.Encode(ViewData["Title"]) %>. If it finds one (which will be the case for the all sample views in the MVC template) then it won't do anything further. If no title exists (if ViewData["Title"] is null or empty) it will default to whatever is defined in your view by the Title attribute :

    <%@ Page Language="C#" MasterPageFile="~/Views/Shared/RRMaster.Master" 
    Title="View Products" AutoEventWireup="true" CodeBehind="ViewProduct.aspx.cs"
    Inherits="RR_MVC.Views.Products.ViewProduct" %>
    

    In my master page I would have removed the runat='server' tag - since I dont think I'll ever want to populate my page title from the view's Title property. But I'm holding off doing this pending Phil's promised blog post on the subject - in case the runat server gives me anything useful for my CSS and JS too.