Setting up a solution with MVC4 and Twitter Bootstrap

Update 9 sept 2013: I originally wrote this post with Bootstrap 2.3. Because this post is quite popular, I updated it for Bootstrap 3]

Starting a new Solution is very easy with Visual Studio 2012. Make sure you have installed the 2012.3 update, NuGet package manager, Git Tools and Web Essentials.

We are going to create a new project. I always start with a blank solution and then add the project, so that I can name the solution and the web project separately. I am going to name the Solution “CloudAuction” and the MVC4 project “Auction.Web”.

image 

image 

image 

I am going to start with Internet Application project template. This template already has a simple controller and view so that we can use it to start setting up the page layout.

image 

This will result in a new website that can be run directly. You will get the well-known MVC starter site. It even has a responsive design (that we’ll replace with something better shortly). If you compile and run, you’ll see this result:

image 

The responsive design that comes with the Internet template is very basic however. Microsoft has never been that great with front-end web technologies, so we’ll need to turn somewhere else to help us out with that. We will useBootstrap as the basis for the front end technology.

I am a huge fan of Bootstrap. It enables me, as a non-designer with very limited css skills, to make sites that look very professional. If you implement responsive design, the site will even work and look well on small screens and mobile devices, without much effort.

We can add Bootstrap to the project using NuGet. There are several packages that offer Bootstrap. In it simplest form, Bootstrap consists of a CSS stylesheet and a javascript file. These are bundled files, bootstrap is a modular and componentized system. The CSS files are compiled from a collection of LESS sourcefiles. One of these files is called variables.less, and this file is meant to be modified easily, which makes it easy to change the color scheme of a site. With Bootstrap being very popular lately and many sites that don’t modify anything to it, our site might look indistinguishable from others. This is unnecessary, as it is not hard to change how a bootstrap site looks, while still having the benefit of using its structured and thoroughly tested css.

In order to be able to modify the styling easily in our MVC project, we need to get the LESS sources in our project. To get these, I am going to import the Twitter.Bootstrap.Less package. Using the package manager console, type:

PM> Install-Package Twitter.Bootstrap.Less

We’ll be using HTML5, but we want our site to work on IE7 and 8 too, so we are also going to need this:

PM> Install-Package html5shiv

The 3.0 version of the Twitter.Bootstrap.Less package will install all of the Bootstrap .less files in the folder /Content/bootstrap. The top-level filebootstrap.less imports all the other files in this folder, and can be compiled to .css. With Bootstrap 2.3, I used the Dotless HttpHandler to do this dynamically. However, Dotless cant’t currently compile the Bootstrap 3 files because it does not (yet?) support Less 1.4. Luckily, the new version of the Web Essentials Visual Studio Add-in recently added support for Less 1.4, and it compiles Bootstrap 3 without any problem. So we will use Web Essentials to pre-compile the Less files in Visual Studio.

Leave the /Content/bootstrap folder where the NuGet puts them (so we can update easily in the future), but copy the bootstrap.less and variables.less files over to a new folder /Content/themes/default. This will be the place for our theme-specific content files. Update the @import statements in bootstrap.less so they point back to the original /Content/bootstrap folder, using a relative path (i.e. @import “..\..\bootstrap\normalize.less”). This is done so we can modify the the appearance of our site without overwriting bootstrap files. We can also easily add other theme folders and place Bootswatch themes in there.

If you save of bootstrap.less, Web Essentials will automatically compile a linked file bootstrap.css and bootstrap.min.css from the combined .less sources. I set the build action of all .less files to “None”, as they don’t have to be deployed after compilation.

image 

The modified bootstrap.less is here on github.

Now we are ready to create our Bootstrap-based page layout and menu. Go tohttp://getbootstrap.com/getting-started/ to see several starter templates, I am using the Jumbotron site as my template.

Here is a basic _Layout.cshtml file. Place it in /Views/Shared. Also design (or steal) some icons for shortcuts and place them in a new “ico” folder under the Content folder.

@using Auction.Web.Utility
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>@ViewBag.Title - My ASP.NET MVC Application</title>
@RenderSection("meta", required: false)
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<link href="~/Content/themes/default/bootstrap.css" rel="stylesheet">

@Html.Partial("_html5shiv")

<!-- Fav and touch icons -->
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="~/Content/ico/apple-touch-icon-144-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="~/Content/ico/apple-touch-icon-114-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="~/Content/ico/apple-touch-icon-72-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="~/Content/ico/apple-touch-icon-57-precomposed.png">
<link href="~/Content/ico/favicon.ico" rel="shortcut icon" type="image/x-icon" />
</head>
<body>
@Html.Partial("_NavBar")

@RenderSection("featured", required: false)

<div class="container">
@RenderBody()
<hr />
<div class="footer">
<p>&copy; Company 2013</p>
</div>
</div>

@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
</body>
</html>
view raw_Layout.cshtml hosted with ❤ by GitHub

 

The navigation bar on top of the page is copied from the Bootstrap samples, with one small MVC addition: it sets a class “active” on the currently active menuitem, so that it will be highlighted by the standard bootstrap styling. The username/login feature is left out for now, I will add it back in another post. The menu is in _NavBar.cshtml, also located in Views/Shared:

@helper ActiveItem(string actionName, string controllerName, string areaName)
{
if (ViewContext.RouteData.Values["action"].ToString() == actionName &&
ViewContext.RouteData.Values["controller"].ToString() == controllerName &&
(ViewContext.RouteData.DataTokens["area"] == null || ViewContext.RouteData.DataTokens["area"].ToString() == areaName))
{
@:active
}
}

<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Cloud Auction</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="@ActiveItem("Index", "Home", null)">@Html.ActionLink("Home", "Index", "Home")</li>
<li class="@ActiveItem("About", "Home", null)">@Html.ActionLink("About", "About", "Home")</li>
<li class="@ActiveItem("Contact", "Home", null)">@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</div>
</div>
</div>
view raw_NavBar.cshtml hosted with ❤ by GitHub

 

Our homepage is in Views/Home/Index.cshtml. It is almost the same as the original one from the MVC template, but it is modified with some Bootstrap css classes.

@{
ViewBag.Title = "Index";
}

@section featured {
<div class="jumbotron">
<div class="container">
<h1>@ViewBag.Title.</h1>
<h2>@ViewBag.Message</h2>
<p>
To learn more about ASP.NET MVC visit
<a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
The page features <mark>videos, tutorials, and samples</mark> to help you get the most from ASP.NET MVC.
If you have any questions about ASP.NET MVC visit</p>
<a class="btn btn-large btn-success" href="http://forums.asp.net/1146.aspx/1?MVC" title="ASP.NET MVC Forum">our forums</a>.
</div>
</div>
}
<!-- Example row of columns -->
<div class="row">
<div class="col-md-4">
<h2>Getting Started</h2>
ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that
enables a clean separation of concerns and that gives you full control over markup
for enjoyable, agile development. ASP.NET MVC includes many features that enable
fast, TDD-friendly development for creating sophisticated applications that use
the latest web standards.
<p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=245151">Learn more &raquo;</a></p>
</div>
<div class="col-md-4">
<h2>Add NuGet packages and jump-start your coding</h2>
<p>NuGet makes it easy to install and update free libraries and tools.</p>
<p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=245153">Learn more &raquo;</a></p>
</div>
<div class="col-md-4">
<h2>Find Web Hosting</h2>
<p>You can easily find a web hosting company that offers the right mix of features and price for your applications.</p>
<p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=245157">Learn more &raquo;</a></p>
</div>
</div>
view rawIndex.cshtml hosted with ❤ by GitHub

 

One small thing to do: we also need to add the bootstrap javascript files so that we can use the advanced components. The best way to do this is to import the individual javascript files from bootstrap and make a bundle containing only those that are used. However, I could not find a nuget package that delivers the original files so for this blog post I’ll take the easy way and use the already bundled bootstrap.js that came with the nuget we used earlier, and wrap it by adding this line in BundleConfig.RegisterBundles:

bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( "~/Scripts/bootstrap*"));

By including this script bundle in a page, the advanced Bootstrap components (popup, typeahead etc) will start to work. In another post I will show how to use the bootstrap carousel component on a page, using knockout.js and SignalR to feed it with images.

With all that in place, we can compile-run our new website, and see MVC4 working server-side, and Bootstrap 3 client-side. The responsive design is working. You can test the page on various devices, it works on almost every smartphone and also on other devices with a browser, such as smart TVs and game consoles. Our project is ready to get started!

image

 

[This post is part of the series Development of a mobile website with apps and social features]