Tuesday, April 10, 2012

Partial View Vs. Display/Editor Templates

ASP.net MVC provides two different options to create re-usable components
  • Partial Views
  • Display/Editor Templates
But whats the different between both of them and what advantage one has got over the other.
Difference between Display and Editor Templates: 
Display templates and Editor templates are model driven templates but only differ by the convention that display should only render read only html like divs, labels or spans etc where are editor should render editable html with forms, input controls, etc. Developers are the one whole create these templates and there is no validation which prevent us to create templates in the opposite order. It is the convention over configuration policy which drives MVC to follow a specific standardize pattern and sticking to this will ensure that no matter what you pass into Display helper method(s) will always render the same result as expected. Once we specify UIHint on any property, we instructor MVC view engine to render the respective property using given template specified either under DisplayTemplates folder or EditorTemplates folder under shared folder depending whether we want readonly mode (Html.Display) or editable mode (Html.Editor).

Sample ViewModel for the same to demonstrate how we ViewModel can be decorated with attributes to leverage templates rendering thru ViewModels in MVC
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using ReferenceImplementation.ViewModels;
 
namespace ReferenceImplementation.ViewModels
{
    public class PersonViewModel
    {
        public string FirstName { getset; }
 
        public string LastName { getset; }
 
        [UIHint("Int")]
        public int Age { getset; }
 
        [UIHint("Date")]
        public DatetimeViewModel DateOfBirth { getset; }
 
        [UIHint("Phone")]
        public PhoneViewModel MobileNumber { getset; }
    }
}
By specifying the UIHint attribute on properties in ViewModel, we are instructing MVC to render these properties with the respective templates (depending on its display or editor reference) from the respective folder instead of using standard MVC editor.
For the view code like the one given below
<div class="readonly">@Html.DisplayFor(m => m.DateOfBirth)</div>
Since we are using Display helper method, MVC will look for the Date template under DisplayTemplates folder and  for the view code given below
<div class="editale">@Html.EditorFor(m => m.Phone)</div>
MVC will look for template under EditorTemplates folder for the Editor helper method.

Difference between Partial View and Display/Editor Templates

By convention, Partial Views are considered to be View Centeric and MVC Templates are considered to be Model Centeric. This means that templates are more dependent on the view model and way they are rendered depends a lot on their properties but same is not true for the partial view as you are more concerned in choosing the correct partial view.
Partial View differs from Templates in the way they render Id's from the ViewModels. Partial view render the element name as it is but MVC Templates adhere to model hierarchies when rendering HTML helpers. e.g if you have a "Bar" object on your "Foo" model, the HTML elements for "Bar" will be rendered with "Foo.Bar.ElementName", whilst a partial will have "ElementName".
MVC Templates are more robust and smart. If you had a List<T> of something in your ViewModel, you could use @Html.DisplayFor(=> m.CollectionOfFoo), MVC templates are smart enough to see it as a collection and render out the single display for each item as opposed to a Partial, which would require an explicit for loop.
Templates are passed with additional information that partial views are not, in particular you receive ModelMetadata, such as that created by attributes. ModelMetadata are part of ViewData which is also accessible in partial view but are null as its only populated in templates ().
Note: Templates are partials which adhere to a specific convention. The situations which make templates better or worse than old partials are almost strictly dependent on whether or not the convention is worth adherence in your application

Monday, April 9, 2012

Bundle and Minification in MVC4

What is meant by MINIFICATION?

As described in wiki ...


"Minification (also minimisation or minimization), in computer programming languages and especially JavaScript, is the process of removing all unnecessary characters from source code, without changing its functionality. These unnecessary characters usually include white space characters, new line characters, comments, and sometimes block delimiters, which are used to add readability to the code but are not required for it to execute."


This is very helpful as we can reduce the size of the javascript file to be downloaded to the client browser from the server which reduces the data to be downloaded and increases the performance


What is meant by BUNDLING?

Bundling is the process of combining all the javascript files into one file so that client browser has to make only one request to the server to download all the files in go. For example, max browser can only process 2 request at a given instance (possibly has increased with the modern browsers). If we have more number of files then they have to wait for browser to request from server once the previous requests are complete which creates delay for the page to get complete resources before it is ready. On the other hand bundling process bundle up all the js files needed to be downloaded into one and does not have to wait for the server to process other request hence increasing the performance of the application. Same can be done for the CSS files.


Bundling and minification go well together as we can reduce the size of the file by minification and bundle up all the files like js and css in there respective file types to reduce the calls to the server.


Figure 1.1 shows a page being loaded with multiple script files. Total time to download all the files and before DOM ready event is fired is 2.14s.




Figure 1.1


Figure 1.2 shows a same page being loaded but this time we are using bundling and minification for the script files. So we have reduced the number of server calls to one and file is loaded in 370ms.


Figure 1.2




Using Bundling and Minification in ASP.net MVC4


ASP.net MVC 4 comes with new feature called bundling and minification.

var mainWebStyle = new Bundle("~/Scripts/libs"typeof(JsMinify));
mainWebStyle.AddFile("~/Scripts/jquery-1.7.1.min.js");
mainWebStyle.AddFile("~/Scripts/Knockout-2.0.0.js");
BundleTable.Bundles.Add(mainWebStyle);

In the above example, we can how bundles are created. This this example, we are bundling up two js file into one lib1 file. we can also bundle all the files in one folder with the following code.

var mainWebStyle = new Bundle("~/Scripts/libs"typeof(JsMinify));
mainWebStyle.AddDirectory("~/Scripts", "*.js", false);
BundleTable.Bundles.Add(mainWebStyle);

And in the view we can refer to  bundled file like this.

<script src="@Microsoft.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/libs")" type="text/javascript"></script>

Microsoft.Web.optimization help to cache the file on the clients machine and at the same time also adds a magical versioning number to the file which changes if file is changed, hence forcing the client to request for new file if file is modified and not refer to cached file on the client side.

We can also use our own minification utility if we dont like the one provided by the microsoft e.g

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Web.Optimization;
using Yahoo.Yui.Compressor;

namespace MVC4Example
{
    public class YuiJsMinify : IBundleTransform
    {
        public void Process(BundleResponse bundle)
        {
            if (bundle == null)
            {
                throw new ArgumentNullException("bundle");
            }

            bundle.Content = JavaScriptCompressor.Compress(bundle.Content);
            bundle.ContentType = "text/javascript";
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Web.Optimization;
using Yahoo.Yui.Compressor;

namespace MVC4Example
{
    public class YuiCssMinify : IBundleTransform
    {
        public void Process(BundleResponse bundle)
        {
            if (bundle == null)
            {
                throw new ArgumentNullException("bundle");
            }

            bundle.Content = CssCompressor.Compress(bundle.Content);
            bundle.ContentType = "text/css";
        }
    }
}


In the above example, i have used Yahoo Yui compressor dll to minify my javascript and style files instead of JsMinify and CssMinify.

Please visit the link of the presentation that Scott Gu gave in Netherlands to demo bundling and minifications and some other new features coming out in MVC 4


Happy Coding