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?
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.