Wednesday, December 7, 2011

Handling all the CSS files and the JS files of your project for better performance

Almost all the web applications that we are involved with will contain multiple javascript files and css files. Best practices suggest to keep the js and css files as much divided as possible during development time, for three main reasons – reduce individual page sizes, enable resuse and to leverage expiration policies on them.

Once published to production, again, for better front end performance, it is suggested that we: first minimize all these and then combine all these into one file each ( one for the js files and the other one for css files). There are many tools out there that allow you to do this – jsmin, YUI Compressor, CSSMin, MicrosoftAjaxMinifier. It is also advised that we do this during build time ( and that too only for release builds).

Wait a second, all these is the what we have now ( year 2011). What about 2012??? Well the King is back in the house – Visual Studio 2011 and with it the ASP.Net vNext (4.5 Dev preview). So, what?

With ASP.Net 4.5, all the above is inbuilt. Yes, you read it right. “Minification and Bundling” is part of ASP.Net 4.5 framework. No more running around external libraries and tools to get this done for you.

By default it is directory based. You keep all the css files and the js files in a specific directory and just link to that directory from your page using something like: <link href=”mystyles/css” rel=”stylesheet”>  for CSS and <script src=”jscode/js” /> for JavaScript files – it is as simple as that. Rest is taken care by the ASP.Net framework – it minimizes all the files, bundles them together into one single file and then includes them as part of the http response.

The above is just the default behavior. The framework also provides extension APIs that you can use to create your own processing for the minification as well for the bundling. And all this you do at your most favorite place in the whole wide world– globasl.asax.cs  :).

Enjooy!

Tuesday, November 22, 2011

Asp.Net MVC ( jQuery Templates) Auto Model Binding To a Complex Type that has a Collection

Posting back collection and getting it to default bind to the controller method parameter is very interesting with Asp.Net MVC 3. This can be achieved using the DefaultModelBinder.
For primitive types it is very easy.. something like below is all you need to do at the view side
<form method="post" action="/Home/UpdateStudentIds">
<input type="text" name="studentIds" value="123" />
<input type="text" name="studentIds" value="234" />
<input type="text" name="studentIds" value="235" />
<input type="text" name="studentIds" value="834" />
<input type="submit" />
</form>

And the controller method will look like below:
public ActionResult StudentIds(ICollection<int> studentIds{
return View( studentIds) // studentIds will be a collection of int
}

The  above is pretty straight forward. Now, what if we have to supply a collection of complex types and that too as part of a complete object hierarchy. For e.g, let us say we need to post back a Teacher object which will have the collection of student entities in it. Just to add more spice to it, let us say that I am using jQuery templates to render the collection details dynamically on the view.

So the below is my Model ( View Model ? ) classes:
public class Teacher{   
public string Name{ get; set; } 
public ICollection<Student> Students { get; set; }
} 

public class Student{  
public string FirstName{ get; set; }
public string FirstName{ get; set; }  
public int StudentId {get;set;} 
}

And the below is my controller method :
public ActionResult UpdateTeacher(Teacher teacher) { 
return View(teacher);
}

So now to the view. The goal is, when the user submits the form back to the server ( controller), everything should get auto bound to the teacher object – the parameter to the controller method. The teacher object should have the collection of students in it with the values passed from the view (client). Also we mentioned, we are going to use jQuery templates at the view to show the list of students the Teacher is associated with. The code for the view is below. I am providing only the razor code and not the related JavaScript code ( the jQuery template binding JavaScript code is pretty straight forward and I am not including it below).
@using (Html.BeginForm("UpdateTeacher", "Teacher"))
{
<fieldset>
 <fieldset>
 <!-- The teacher name -->
 @Html.LabelFor(model => model.Name)
 @Html.TextBoxFor(model => model.Name)
 <div>
 <!-- The student details -- this is the header row -->
 <table id="studentTbl">
 <thead>
 <tr>
  <th>
   First Name
  </th>
  <th>
   Last Name
  </th>
 </tr>
 </thead>
 <!-- this is the student details to be filled in by the jquery template script below -->
 <tbody id="studentTblBody">
 </tbody>
</table>
</div>
</fieldset>
<!-- student details - row by row -->
<script id="studentDetailsTemplate" type="text/x-jquery-tmpl">
<tr>
 <td>
  <input type="hidden" name="Students.Index" value="${StudentId}" />
  <input type="hidden" name="Students[${StudentId}].StudentId" value="${StudentId}" />
  ${FirstName}
  <input type="hidden" name="Students[${StudentId}].FirstName" value="${FirstName}" />
 </td>
 <td>
  ${LastName}
  <input type="hidden" name="Students[${StudentId}].LastName" value="${LastName}" />
 </td>            
</tr>
</script>
<!-- and finally the button to submit -->
<fieldset>
<div>
 <input type="submit" value="Save" id="Save" />
</div>
</fieldset>
</fieldset>
}

that is it….rest is magic

Line 28 to line 41 is what does it. If you watch closely, for each row, for each element, we have added an input tag to represent that element. Inside here we need to recreate the collection in such a way that when the whole data is sent back, the DefaultModelBinder will be able to bind it to the action parameter. The name of the elements is what the DefaultModelBinder uses to create the collection. So if the names are indexed, then it will create a collection with the same name. The name of the collection inside the teacher is Students. So the name of each of these elements should also be indexed around the “Students” name. And also to provide an unique index to each of the element for each row, we have used the StudentId property since it will be unique for each student. So in effect, when the data is posted back to the server, the collection is sent back like Students[123].FirstName = “XXX”, Students[123].LastName =”YYY”, Students[234].FirstName =”AAA”, Students[234].LastName = “BBB” etc. Using this information it will be able to create a collection of Students and since it comes as part of the form post which contains the teacher object details it will  tie the collection to the teacher object as well.

Ok… . I would encourage the reader to take the above code snippets and try it out in a complete form.

Phil Haack had blogged about this DefaultModelBinder in his blog -- http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx --  , however one of the comments to his blog was how would you do it if the collection was part of an object hierarchy. I added the jQuery template part also to deal with the collection in the view – the project I was working on was using jQuery Templates heavily. You can get more details on the jQuery Templates at http://api.jquery.com/category/plugins/templates/ .

Code for peace!

Best,

Monday, September 26, 2011

Starts Blogging

Yes, it is peer pressure, and also the absolute need of getting away from the habit of making small notes, reading some good stuff, finishing something new successfully -- and then forgetting all about that. Will make a dedicated effort to get the right things up here -- mostly will be technology, and once in a while will focus on my personal philosophies :).