CoffeeScript Custom Processor in ASP.NET MVC 4 Beta

With the release of ASP.NET MVC 4 Beta, there was a cool feature added called bundling, which I wrote about.

alt text

CoffeeScript is a library that has received a lot attention from the community and having the ability to create custom bundlers in ASP.NET MVC 4, we can now create a very clean processor for the library.

After downloading ASP.NET MVC 4 and creating a new project, install the CoffeeSharp package from Nuget. This package is a CoffeeScript compiler for .NET and we are going to use it to process our CoffeeScript files.

To create a custom bundle processor, we need to create a new type that inherits from the IBundleTransform interface. The interface has a single method that we need to implement which is the Process method that passes a BundleContext as well as a BundleResponse. The response object will contain a collection of files.

Using CoffeeSharp a very simple implementation that will work is the following

public class CoffeeCompiler : IBundleTransform
{
    public void Process(BundleContext context, BundleResponse response)
    {
        var coffeeScriptEngine = new CoffeeSharp.CoffeeScriptEngine();
        string compiledCoffeeScript = String.Empty;
        foreach (var file in response.Files)
        {
            using (var reader = new StreamReader(file.FullName))
            {
                compiledCoffeeScript += coffeeScriptEngine.Compile(reader.ReadToEnd());
                reader.Close();
            }
        }
        response.Content = compiledCoffeeScript;
        response.ContentType = "text/javascript";
        response.Cacheability = HttpCacheability.Public;
    }
}

In our Global.asax.cs we can now register our newly created CoffeeScriptCompiler and tell it to process .coffee files.

var coffeeBundle = new DynamicFolderBundle("coffee", new CoffeeCompiler(), "*.coffee");
BundleTable.Bundles.Add(coffeeBundle);

The first parameter is the suffix, the second is the type that will be tasked with processing the bundle and lastly the search pattern.

Now we might have some coffee scripts that live in ~/CoffeeScripts. We can now use our newly created weapon and task it to perform it's magic.

<script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/CoffeeScripts/coffee")"></script>

After running the project the output should be similar to the following screenshot

alt text

Here is a sample project

What's new in ASP.NET MVC 4 Beta?

There are some very awesome features that came with the release of ASP.NET MVC 4. Here is a list of them and some samples on how to use them.

Razor now supports the ~ semantic

How many of you are tired of seeing the following bit of ugly code?

<link href="@Url.Content("~/Content/css/style.css")" rel="stylesheet" type="text/css" />

With the new feature, you can now write (a little less fluff)

<link href="~/Content/css/style.css" rel="stylesheet" type="text/css" />

Minification and Bundling

This is a feature that I am sure a lot of developers will absolutely love.

Bundling is the ability to bundle a set of files. The less requests to the server, the better. For example, let's assume you are using twitter's bootstrap and your own set of custom styles in a separate file but they are both inside of a folder called "/Content". By using the BundleUrl method from the System.Web.Optimization namespace, it will bundle the css up into a single css and serve that to the client's browser. However, there are 2 ways that you accomplish this and the one does offer something above the other.

the first way uses a convention based approach

<link href="/Content/css" rel="stylesheet" />

the second uses the ResolveBundleUrl which caches the minified file on the client for a year by using a hash to check if the file has changed, otherwise it will not even request the file.

<link href="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Content/css")" rel="stylesheet" type="text/css" />

Here is a comparison between the 2 as served to the client

alt text

Custom Rules With the bundling comes, custom bundling, the ability to create our own bundles by using the Bundle class and registering that in the BundleTable and after that being able to reference your custom bundle name in the application.

var bundle = new Bundle("~/YourScripts", typeof([JsMinify][6]));
bundle.AddDirectory("~/someScripts", "*.js", true); //include sub folders
BundleTable.Bundles.Add(bundle);

Custom Processing Let's assume that you also want to implement something like CoffeeScript or Less that requires different kind of processing, the team has also given us the ability to provide that functionality by using DynamicFolderBundle

i.e.

var coffeeScript = new DynamicFolderBundle("coffee", typeof(CoffeeTransform), "*.coffee");
BundleTable.Bundles.Add(coffeeScript);
BundleTable.Enabled = true;

More resources :

Scott Guthrie's post on the ASP.NET MVC 4 Beta

Bundling and Minification Exercise on MSDN

In the coming weeks, I will dig a more into this, but for now, Start New Project your way into ASP.NET MVC 4 Beta (which comes with a golive license)

Good looking ASP.NET MVC notifications with Bootstrap

I have been a long time fan of twitter's bootstrap and always contemplating on ways to create a template that I can use for all my ASP.NET MVC projects.

The one part of the template that i'm currently using is that my services gets injected into my controllers' constructors.

public class UserController : BaseController
{
    private IUserService userService;
    /// <summary>
    /// Initializes a new User Controller
    /// </summary>
    /// <param name="userService"></param>
    public UserController(IUserService userService)
    {
        this.userService = userService;
        this.userService.FailureOccurred += new EventHandler<MessageEventArgs>(base.OnFailureOccurred);
    }
}

I wanted to leverage this and therefor had all my services inherit from a common service that will expose a list of messages as well as raise an event once a failure occurred.

public interface IUserService : IService
{
    /// <summary>
    /// Registers a User
    /// </summary>
    /// <param name="user"></param>
    /// <returns></returns>
    bool RegisterUser(User user);
}

By using a simple extension method, we can spit out all the messages at any point in time. For the purpose of the sample project, I call the extension method in the _Layout.cshtml.

alt text

The extension method makes use of bootstrap's good looking alert-message css classes alt text

You can find the sample project here.

A Circular reference was detected while serializing

If you ever ran into a scenario where you have to create a cascading drop down list in ASP.NET MVC and everything seems to be going well until you decide to actually use it and then nothing…

alt textalt text

You check your controller method, you check your script, you cannot understand why this problem is creeping up...

/// <summary>
/// Get Models
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public JsonResult GetModels(int id)
{
    CreateSampleData();
    var query = from make in makes
                where make.ID == id
                select make;
    var result = new JsonResult();
    result.Data = query.First();
    result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
    return result;
}

<script language="javascript" type="text/javascript">
    $(document).ready(function () {
        $("#Makes").change(function () {
            var url = "/Home/GetModels";
            $("#Models").empty();
            $.getJSON(url, { id: $("#Makes").val() }, function (data) {
                $.each(data, function (index, optionData) {
                    $("#" + selectedModel).append("<option value=" + optionData.ID + ">" + optionData.Name + "</option>");
                });
            });
        });
    });
</script> 

... until you run fiddler.

alt text

This problem is caused by the circular references to the data that you are passing back

alt text

The fix is to just pass back what you need

/// <summary>
/// Get Models
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public JsonResult GetModels(int id)
{
    CreateSampleData();
    var query = from make in makes
    where make.ID == id
    select make; 

    var data = from model in query.First().Models
    select new { ID = model.ID, Name = model.Name }; 

    var result = new JsonResult();
    result.Data = data;
    result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
    return result;
}

Reusing ASP.NET MVC Models using the Model Binder

This might not be immediately obvious to everyone but the model binder can be used for just more than just your average model binding.

For example, let’s say that you have the following scenario. You want to be able to register a user, so you go ahead and you create a RegisterUserViewModel.

public class RegisterUserViewModel
{
    [Required]
    public string Username { get; set; }
    [Required]
    [Display(Name="Email Address")]
    public string EmailAddress { get; set; }
    [Required]
    [MinLength(6)]
    public string Password { get; set; }
    [Required]
    public string ConfirmPassword { get; set; }
}

Now that you have this specific view model setup, you create a strongly typed view. You perform some javascript validation and the user clicks on the “Let’s do this” button and you get the controller. This is where you perform the magic of creating the user, but do you really need all the fluff of the ConfirmPassword? What about a simple UserViewModel

public class UserViewModel
{
    [Required]
    public string Username { get; set; }
    [Required]
    public string Password { get; set; }
}

that will only give you what you really care about and keep your controller actions a bit more generic?

The ASP.NET MVC ModelBinder will take care of this for you

Sure, there are problems with this such as passing through the model back to the typed view, but the idea is to come up with nifty and clever tricks that you will one day be able to use.

Cascading DropDownList with ASP NET MVC 2 and JQuery

First we will need to setup the JsonResult controller action.

/// <summary></summary>  
/// Get Models
/// <param name="makeID" />  
/// <returns></returns>  
public JsonResult GetModels(string id)  
{   
    JsonResult result = new JsonResult();   
    var filteredModels = from model in homeViewModel.Models   
                         where model.MakeID.ToString() == id  
                         select model;   
    result.Data = filteredModels.ToList(); 
    result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
    return result;  
} 

This method now gives us the ability to use the nifty $.getJSON jquery call. The signature for the call is as follows

jQuery.getJSON( url, [ data ], [ callback(data, textStatus) ] )

Given that we have setup 2 Drop Down Lists, one for Makes and the other for Models, like so.

Html.DropDownListFor((model) => model.MakeID, new SelectList(Model.Makes, "ID", "Description")) Html.DropDownListFor((model) => model.ModelID, new SelectList(Model.Models, "ID", "Description"))

we can include the following bit of jquery

//Hook onto the MakeID list's onchange event  
$("#MakeID").change(function() {   
//build the request url   
var url = '<!--Url.Content("~/")-->' + 'Home/GetModels';

//fire off the request, passing it the id which is the MakeID's selected item value   
$.getJSON(url, { id: $("#MakeID").val() }, function(data) {    
//Clear the Model list    
$("#ModelID").empty();    
//Foreach Model in the list, add a model option from the data returned    
$.each(data, function(index, optionData) {     
  $("#ModelID").append("<option value=" + optionData.ID +">"+optionData.Description+"</option>");    
});   
});  
}).change();

ASP.NET MVC 4 Developer Preview

ASP.NET 4 Developer Preview was recently made available and with that comes an updated default template. As developers, we don’t always have the necessary design skills to put something together that will look good (Hey, it works, what’s your problem). I think apart from the additional features that it’s great that all aspects of this framework gets some attention.

I would so the major feature in this release was a focus on compatibility between desktop and mobile browsers. With the growth of tablets and mobile devices, it will be more important than ever for developers to ensure that their sites are compatible with these form factors.

 What’s new in ASP.NET MVC 4?

  • Refreshed Default Project Templates
  • Mobile Project Template
  • Display Modes
  • Recipes
  • Task Support

I am going to have a look at some of the other features, such as the Display Modes, the View Switcher and Task Support overt the next couple of days.

Another template I really like, and I don’t know, but it’s probably because it feels very IPhony, is the Mobile Template

You can read more at http://www.asp.net/learn/whitepapers/mvc4-release-notes

The ViewModel is a Model of the View

In the mvc.tutorial series, we setup a simple ASP.NET MVC project, configured our DbContext for Dependency Injection and today we are going to look at what benefits a ViewModel gives us over creating strongly typed views against our models, which in this case is tied to our ORM (Object Relational Mapper)

My first instinct after creating my controller and index action in the controller, is to add a new strongly typed view.

alt text

What's wrong with this? Well, nothing, your model classes aren't really tied to Entity Framework. You have just informed Entity Framework that you would like to use those classes as tables inside of your DbContext.

Since your classes aren't tied to the ORM, what about validation and using the DataAnnotations

alt text

This is where I see problems creeping up. For example, let's take a simple registration on a site. You have this User, the user is required to enter a username, password and email address to register. So, what we do is decorate each property with the RequiredAttribute. Now we can go and create a strongly typed view.

/// <summary>
/// User
/// </summary>
public class User
{
    [Required]
    public string Username { get; set; }
    [Required]
    public string Password { get; set; }
    [Required]
    public string EmailAddress { get; set; }
}

This is all fine and dandy, but now, after many lines of registration code, we decide that we need a Sign In View. For a user to sign in, we only require the username and password, what do we do now? If we had to create a strongly typed view from the User now, our Model State will not be valid on form post as the email address is required.

This is where View Models come in handy. What you could do is create a View Model that describes the view. e.g.

/// <summary>
/// Register User View Model
/// </summary>
public class RegisterUserViewModel
{
    [Required]
    public string Username { get; set; }
    [Required]
    public string Password { get; set; }
    [Required]
    public string EmailAddress { get; set; }
}

/// <summary>
/// Sign In User View Model
/// </summary>
public class SignInUserViewModel
{
    [Required]
    public string Username { get; set; }
    [Required]
    public string Password { get; set; }
}

You can still use the Data Annotations and your views will only get the data that they require.

The following article, describes how to map data from a Model to a View Model AutoMapper

What does dependency injection give us?

In a previous article, we setup a simple ASP.NET MVC project and added references to Entity Framework as well as a dependency injector called Ninject.

What does this dependency injector give us?

Let's take a look at an example.

You have 2 controllers in your ASP.NET MVC project, the first is used to administrate your films and the other is to administrate your actors. In each of the controllers, you have a dependency of a DbContext.

How do you handle this scenario? You could create it and cache it, but then you need to write some code to retrieve it.

That's what Dependency Injectors are there for. That's what Ninject is there for, so let's see how it will make the magic happen. In the previous post we added the references using nuget and now we are going to use them.

Ninject expects you to register modules with the Kernel. Modules are little units that inform ninject of what dependencies you want to register and how you want them constructed and configured.

e.g.

/// <summary>
/// Database Module
/// </summary>
public class Database : NinjectModule
{
    /// <summary>
    /// Load
    /// </summary>
    public override void Load()
    {
        Bind<IObjectContextAdapter>().To<MovieContext>().InRequestScope();
    }
}

In the App_Start folder/directory that Ninject created when it was installed, navigate over to the RegisterServices inside of the NinjectMVC3.cs file. We are going to ask Ninject to register all the modules located in the executing assembly.

e.g.

kernel.Load(Assembly.GetExecutingAssembly());

Ninject is all ninjad up and ready to go, inside a controller, let's add a constructor and give it a DbContext as a parameter.

e.g.

public class FilmController : Controller
{
    private MovieContext db;

    public FilmController(IObjectContextAdapter movieContext)
    {
        db = movieContext as MovieContext;
    }

Shakes head, that wasn't difficult was it? That's called Constructor Dependency Injection

In the next tutorial, we will look at not strongly typing your views to your data model, but to an intermediary object called a ViewModel.