Setting up a minimal ASP.NET MVC project in Visual Studio, part 3

If you followed my previous two post (here and here) then you should have your ASP.NET MVC project up and running, and if you’re anything like me, you’ll be happy to know exactly what it contains and that it contains no more. Until you start building your application, then you will notice there are some essential things still missing, mainly configuration settings. Let’s see if we can add the last bit of configuration to get the project to a more convenient working state.

Reference assemblies and import namespaces for the views

Just like regular WebForms, ASP.NET MVC views are compiled in a separate process by the ASP.NET compiler. The assemblies you have referenced from your project in Visual Studio are not those available to the ASP.NET compilation process. You need to reference them explicitly in the <compilation> element in the web.config file:

<compilation debug="true">
    <assemblies>
        <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
        <add assembly="System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        <add assembly="System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    </assemblies>
</compilation>

Referencing these assemblies means that you can now import the namespaces and use the types from these assemblies in your views. You can do that with the import directive: <%@ Import %>. Directives are instructions to the ASP.NET page parser and compiler, the import directive instructs the parser to issue a using statement on your behalf when it generates the class code for your page.

<%@ Import Namespace="System.Collections.Generic" %>

Some namespaces are used in most if not all your pages, and having to write these import directives over and over in your views gets real old real fast. Luckily we can specify global imports in our Web.config inside the <pages> element:

<pages>
    <namespaces>
        <add namespace="System.Collections.Generic"/>
        <add namespace="System.Linq"/>
        <add namespace="System.Web.Mvc"/>
        <add namespace="System.Web.Mvc.Html"/>
    </namespaces>
</pages>

The machine configuration already references a set of assemblies and namespaces for you so ASP.NET WebForms work out-of-the-box. However, these configuration files are not updated when you install ASP.NET MVC. In fact, they have not been updated since .NET Framework 2.0 since they are specific to the CLR which is still at version 2, even if you have the latest .NET Framework 3.5 SP1 installed.

In the examples above I have added only the most useful assemblies and namespaces, you will add more if and when you need them. Of course, the System.Web.Mvc and Routing assemblies and System.Web.Mvc.Html namespace are needed, even creating hyperlinks is difficult without these. You will use the System.Collections.Generic namespace often in MVC views, since we normally loop over our data directly instead of databinding a control in our code-behind. The System.Core assembly and System.Linq namespace allows us to use the new LINQ methods in our code.

Configure the C# 3.0 Compiler

The latest version of C# brings a lot of new code constructs to the language, and you will want to use them in the code blocks in your MVC views as well. To do so, you have to configure the C# language provider to use the latest version of the compiler. This is done in the <system.codedom> configuration section.

<system.codedom>
    <compilers>
        <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
            <providerOption name="CompilerVersion" value="v3.5"/>
            <providerOption name="WarnAsError" value="false"/>
        </compiler>
    </compilers>
</system.codedom>

Generic View Pages

A pattern you will see often in ASP.NET MVC is to have the view page inherit from the generic System.Web.Mvc.ViewPage<T> class, so that it will surface a strongly typed model (of type T) that you can use in the view. For this you can specify the type inside the Inherits attribute in the Page directive:

<%@ Page Inherits="System.Web.Mvc.ViewPage<Object>" %>

However, for this syntax to work you have to specify a special page parser that is included with ASP.NET MVC.

<pages pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
    //...
<pages>

This parser works for C# and VB.NET as well. It will recognize the generic notation and will make sure the generated page class will inherit from the generic view type with the type parameter(s) you specify.

Conclusion

Finally! We now have our minimal ASP.NET MVC project and we have added all the required elements and configuration by hand to gain a better understanding of the inner workings of the MVC project type. In this last post of the series we have added several convenient configuration settings to reference assemblies and use namespaces in our (optionally generic) views.

Right now, configuration for IIS 7 is missing from the Web.config. I still use Windows XP and Windows Server 2003, so I haven’t tested out these settings. If you run Windows Vista or Windows Server 2008 you may need to make further adjustments.

Hope this helps!