MVC 3, MVC4, Razor, Technical

Using MVC4 bundling and minification in an MVC3 project

When you push any site to production, you should at least do some basic front end optimisation. Running through a number of optimisation steps will ultimately make your website load quicker and feel more responsive to the end user.

If this is the first you have heard about front end optimisation, I must recommend that you read “High Performance Websites” by Steve Souders.

One of the best ways to make your site load quicker is to make it smaller. Reduce the amount of data that needs to go from your server to the client machine. And one of the best ways to make massive gains in doing this is to Bundle and Minify the CSS and Javascript that your application uses.

MVC4 has made this incredibly easy with built in Bundling and Minification. However, you do not need to upgrade your entire MVC project to take advantage of this fantastic new set of features.

Firstly, open up the project that you want to optimise. I’ll be demonstrating this with a new empty MVC3 web application. Currently, the head of my _Layout.cshtml file looks like this:


<head>
 <title>@ViewBag.Title</title>
 <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
 <script src="@Url.Content("~/Scripts/jquery-1.7.1.js")" type="text/javascript"></script>
 <script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
 <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
 <script src="@Url.Content("~/Scripts/modernizr-2.5.3.js")" type="text/javascript"></script>
</head>

So lets run the page and just see what’s going on under the hood:

IndexPage

So at the moment, my page is a massive 355.89 Kilobytes – and all it does is display some text – “Index”. That’s way too big – and we can see that the biggest and slowest loading areas of the site are the Javascript libraries that are being pulled onto every page of the site. (It’s worth noting at this point that you could used the already minified versions of the files. For the sake of this demo, I’ll be using the full fat versions).

So let’s get bundling and minifying.

Open the package manager console, and enter the following command to drag down the Microsoft ASP.NET Web Optimization Framework:

  •  Install-Package Microsoft.AspNet.Web.Optimization -Pre

Once added to your project, you can the begin configuring your bunding and minification. Open your Global.asax.cs file and add a reference to System.Web.Optimization


using System.Web.Optimization;

Then, go ahead and create a new static method, RegisterBundes:


public static void RegisterBundles(BundleCollection bundles)
{

}

Now, lets create some Bundles. I’m going to put all of my Javascript into one minified bundle, and my CSS into another minified bundle:

public static void RegisterBundles(BundleCollection bundles)
{
//CSS
 var styles = new StyleBundle("~/Content/bundledcss").Include("~/Content/site.css");

//JS
 var js = new ScriptBundle("~/Scripts/bundledjs").Include("~/Scripts/jquery-1.7.1.js",
 "~/Content/jquery.validate.js",
 "~/Content/jquery.validate.unobtrusive.js",
 "~/Content/modernizr-2.5.3.js");

bundles.Add(styles);
 bundles.Add(js);
 BundleTable.EnableOptimizations = true;
}

There are three types of bundle that you can create:

  • Bundle – a non-minified bundle of a collection of files
  • StyleBundle – a minified bundle of a collection of css files
  • ScriptBundle – a minified bundle of a collection of Javascript files

Now, lets wire up a call to our new RegisterBundles method. In Global.asax.cs, locate your Application_Start method. Add the following line:

RegisterBundles(BundleTable.Bundles);

Now, when your application starts up, the bundles will be created. Now, all we need to do is to tell the views that they now need to load a bundled file and not the raw, unbundled and unminified css and js files.

In your _layout.cshtml file, or whichever file you have your stylesheets and javascript files referenced, swap out your raw file references. Firstly, add a reference at the top of your view to System.Web.Optimisation:

@using System.Web.Optimization

Now, lets swap the old references to our full fat files out:

 <link rel="stylesheet" type="text/css; href="@BundleTable.Bundles.ResolveBundleUrl("~/Content/bundledcss")" />
 <script src="@BundleTable.Bundles.ResolveBundleUrl("~/Scripts/bundledjs")">"</script>

And that’s us. Let’s test it out. Remember to build first:

IndexPageOptimised

And we’ve made a massive improvement. We have:

  • Reduced the number of requests (from 6 to 3, as we’ve bundled multiple files into one
  • Reduced the file sizes

This won’t take long to bring into an existing site and is definitely worth the benefits.

Edit: Of course, you should also move your Javascript to the foot of the html document for even more speed improvements.

MVC 3, Technical, Unit Testing

Mocking HttpContext (And setting it’s session values)

Thanks to this Stack Overflow answer that pushed me in the right direction, I was able to mock HttpContext and set values that it encompasses.

Firstly, you will need a helper somewhere in your test project that will return you a mock HttpContext:

public static class MockHelpers
{
  public static HttpContext FakeHttpContext()
  {
    var httpRequest = new HttpRequest("", "http://localhost/", "");
    var stringWriter = new StringWriter();
    var httpResponce = new HttpResponse(stringWriter);
    var httpContext = new HttpContext(httpRequest, httpResponce);

    var sessionContainer = new HttpSessionStateContainer("id", new SessionStateItemCollection(), new HttpStaticObjectsCollection(), 10, true, HttpCookieMode.AutoDetect, SessionStateMode.InProc, false);

    SessionStateUtility.AddHttpSessionStateToContext(httpContext, sessionContainer);

    return httpContext;
  }
}

You will then need to Add and Reference System.Web in your test project. Once done, you will be able to set your HttpContext and set HttpContext specific values, such as session variables. In the example below, I am setting up the HttpContext in the SetUp method of a unit test:

  
[SetUp]
public void SetUp()
{
	HttpContext.Current = MockHelpers.FakeHttpContext();
	HttpContext.Current.Session["SomeSessionVariable"] = 123;
}

Another more heavy solution to the above would be to use a factory to get at and create your session. I opted for the solution above as it meant not changing my application code to fit in with my unit tests.

Entity Framework, Technical

Seed data from SQL scripts using Entity Framework Migrations (EF 4.3 +)

Normally you would add seed data using native C#.

You can also execute arbitrary SQL statements. To do so, in your Seed method (which can be overriden from your Migration folder in your Configuration class), simply read the contents of any SQL files you want to execute, and tell the context to run them:

internal sealed class Configuration : DbMigrationsConfiguration<MyDbContext>
 {

protected override void Seed(MyDbContext context)
 {
  var baseDir = AppDomain.CurrentDomain.BaseDirectory.Replace("\\bin", string.Empty) + "\\Migrations";

  context.Database.ExecuteSqlCommand(File.ReadAllText(baseDir + "\\DataClear.sql"));
  context.Database.ExecuteSqlCommand(File.ReadAllText(baseDir + "\\Table1Insertssql"));
  context.Database.ExecuteSqlCommand(File.ReadAllText(baseDir + "\\Table2Inserts.sql"));
 }
}

The above code will execute DataClear.sql, Table1Inserts.sql and Table2Inserts.sql, which are all in the root of my migrations folder.

Don’t forget that you can generate your insert statements using management studio, or by using the Static Data Generator tool.

 

Technical

HTML and CSS layout frameworks

Here’s a brief list of some great HTML and CSS frameworks. I’d recommend that all sites being developed now use a good CSS layout engine – doing so will save you hours of development time in tweaking CSS just to get your layout right, and will mean that you have more time to focus on the core goal of you application. Enjoy:

MVC 3, MVC4, Technical

Dependency Injection with ninject.mvc3 nuget

Quick post, just because this is mega easy.

Traditionally, adding dependency injection with any standard injection package to an MVC solution would normally mean that you would have to write a Controller Factory and wire it up in your Application_Start() method.

If you want to add dependency injection into an MVC solution, just add one of the pre-baked nuget packages that does the MVC wire up for you:

It’s just much easier – these packages contain code that has done the legwork of wiring up a custom controller factory for you.

Looking specifically at the Ninject.MVC3 package, simply add the NuGet reference. This will add a “NinjectWebCommon.cs” file into your “App_Start” folder:

You can then edit the RegisterServices(IKernel kernel) method to configure your bindings:

        private static void RegisterServices(IKernel kernel)
        {
            kernel.Bind<IWorkRepository>().To<WorkRepository>();
        }
JSON, Technical, WCF

ASP.Net Web API vs RESTful WCF services

With the upcoming release of asp.net 4.5, which includes the fantastic looking ASP.Net Web API, many of us will be thinking that this almost stands on the toes of WCF slightly.

Well not quite.

The two really can serve very different purposes.

  • WCF is designed so that all of your connectivity and endpoints are abstracted away from the core operations of the service (Although you may need to apply certain attributes to your operation contract)
  • All of the connectivity and endpoint data is largely configured through the Web.Config file (and you really should be read up on what your settings do before trying to tweak them)
  • WCF therefore allows you to switch out endpoints and connections through the Web.Config file without the need for recompiling (for example, if you wanted to disable SOAP on a SOAP and JSON web service)

That’s a lot of power.

So the question is, what if my intention is to only ever create a RESTful webservice and I never need to support other message types (such as SOAP)? Should I be using WCF?

Well, the short answer is that you can, but you’d be using a sledgehammer to crack a nutshell. Another major factor will be the issue that WCF doesn’t really let you go all the way with REST very easily:

  • All WCF requests for webHttpBindings are steered towards only using GET [WebGet] and POST [WebInvoke]
  • Enabling other HTTP verbs can involve configuration of IIS to accept request of that particular verb on .svc files
  • Passing data through parameters using a WebGet needs configuration. The UriTemplate must be specified

I’m a big fan of the KISS principle.  So if you are going to setup a Web Service and don’t need SOAP, you should take a good look at the ASP.Net Web API.

But what do the experts say?

Well, Christian Weyer, who basically had a hand in WCF’s inception, states in this blog post that the web is going in a new direction, focused around lightweight web based architectures. He is leaning toward using the ASP.Net Web API for these sorts of architectures.

Further Reading

apigee have made a fantastic ebook on Web APIs available to download for free. It’s a great read, and got me thinking about web services in more detail.

Web-API-Design-apigee-Brian-Mulloy

Entity Framework, MVC 3, Technical

Entity Framework – Plural and Singular Table names

By default, the Entity Framework will assume that all of the names of your tables in your database are either pluralised, or in the case of code first, you would like them to be pluralised when created.

E.g. you have a table called “Product” and not “Products”, or you want your table to be called “Product” and not “Products”

This is the problem that I had. My MVC application consisted of one web page that just dumped out the contents of the “Product” table onto the page. When I browsed to the page, I got an “Invalid object name ‘dbo.Products’.” yellow screen of death runtime error.

The Solutions

1. Rename the table to “Products”. I didn’t want to do this as I’m from the school of singular table names. I was also curious about situations where the tables couldn’t be renamed.

2. Make use of Entity Framework’s fantastic Conventions, that allow you to specify how you have or want your database to be setup.

To tell Entity Framework not to pluralise database table names, simply add the following code into your DbContext class:

public class EfDbContext : DbContext
 {
  public DbSet&lt;Product&gt; Products { get; set; }
  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
    modelBuilder.Conventions.Remove&lt;PluralizingTableNameConvention&gt;();
  }
 }

This code will remove the Pluralising convention that is by default attached to all model builders. You will then be able to access database tables with Singular names.

Links

Table Naming Dilemma: Singular vs. Plural Names (StackOverflow)

PluralizingTableNameConvention Class (MSDN)

SQL Server 2012, Technical, Visual Studio

Visual Studio 2010 and SQL Server 2012 server explorer integration

SQL Server 2012 Express is now available to download from this link.

After downloading it and installing it, I tried to integrate it into an existing project in Visual Studio through the Server Explorer, and got the following issue:

This server version is not supported. Only servers up to Microsoft SQL Server 2008 are supported
This server version is not supported. Only servers up to Microsoft SQL Server 2008 are supported

This is apparently a known issue, and happens when you right click on “Data Connections” in Server Explorer, and chose “Create New SQL Server Database”.

The workaround:

The work around is to create your database using Management Studio (Just the DB, not the actual schema).

Once it has been created, you can then “connect” to the database in Visual Studio’s Server Explorer:

Server Explorer Data Connections Add Connection

This will allow you to connect to the database created in Management Studio without any issues.

If you didn’t change it during installation, your instance name will be “.\SQLEXPRESS”.