Saturday, January 29, 2011

MVC 3 – Razor Syntax Introduction

 

Razor has been one of the most anticipated additions to the third release of MVC. So far, for me, it has made it very easy to quickly shape views.

So, a brief description of Razor would be … ?

A way to use a new markup (NOT the same old <% [code here] %> server code escape syntax) but something new, cleaner, and a bit more intuitive, IMHO.

Razor was first made available in the WebMatrix tools, so you may have seen it here.

How does one use this in an MVC project?

To use it, one must have installed the MVC 3 framework, as it is included as part of this.  When you create a project, open up a view from the initial pages created, you will notice it has the ‘@’ –symbol peppered throughout. This is what Razor uses as an escape sequence.

The first thing you should know, since you probably are already familiar with the <%…%> notation, is that you are still able to place code-blocks into your view. With Razor it is done like this:

@{
View.Title = "MVC3 Test Page";
LayoutPage = "~/Views/Shared/_Layout.cshtml";
}

This code just sets the title of the current view and the LayoutPage’s location [which is equivalent to a MasterPage].


By the same token, one may also introduce server-side properties with similar notation, such as:

This page was created by @View.Name and Copyright @View.CopyrightYear. Please contact @View.AdminEmail for more information.




The above line really exposes the clean nature of Razor’s ‘@’ syntax.


One may also use this syntax to write multiline comments:

@*  This is a comment
that spans multiple
lines.
*@



Easy enough. You can also include code in here, and the rendering engine will ensure that these are comments, and are rendered as text but not executed.

@*
var i = 99;
for(var count = 199; count >= i; count--)
{
//found an easier way, using foreach
// see below.
}
*@




Of course, the above would be rendered as a comment in HTML and not executed.


One may build tables with Razor just as easy, but if you are doing too much work with a table that displays a subset of data, one may want to use the new WebGrid, which I plan to cover soon.

<table>
@foreach(var item in listOfItems){
<tr>
<td>@item.Name</td><td>@item.Value</td>
</tr>
}
</table>


While, for, and other loops are treated no differently than this. One may also use decision statements similarly, such as if/else if/else and switch statements.


In summary, I’ve given a brief introduction to Razor, why it is much preferred to the older escape notation (<%…%>) and how to use it in certain situations to add code to HTML pages.


The next time I will get into some of the major additions that Razor brings along, such as the Html extension methods and reusing HTML helpers.


Wes

Friday, January 28, 2011

Using jQuery to Call A Controller Asynchronously in MVC

Recently, I started re-exploring the newest MVC framework. Since I had not dabbled in the ASP.NET MVC Framework since Summer of 2008 (it was, at this point, in a late beta state, if memory serves me correctly), I had a lot of catching up to do…
The latest design pattern I worked with before this was MVP,  with which I have done 100% of my projects since 2007. MVC, I learned was a couple of more steps towards a well thought-out, well designed framework for web development.
Well, my opinions aside, the first stumbling block I encountered was, “How the heck do I make smooth page interaction in a semi-elite way (meaning: I don’t want to find an <asp:UpdatePanel /> equivalent; I want to do this and actually learn something new in the process).
Enter jQuery. It has been bundled with Visual Studio since VS2010 was released. It has helped me in the past conquer some sticky situations with validation, UI tricks, and helping me shorten my JavaScript. That being said, I am by far no expert in it, so to tackle AJAX with jQuery was going to take some reading.
After scanning some introductory texts on the MVC 3 release, I read that this is the first time that action methods can receive Json-encoded data as parameters. This is covered more in bullet number 3.
My goal was to have two dropdowns,
  1. Activity Categories
  2. Activities
The ever-so-common page interaction comes up—how can I smoothly make the list of Activities be based on the selected Category?
Here goes:

1) Client-side Event Handlers To Spawn AJAX Calls

Define the client-side event handler for the category selection changed event. (yeah, sometimes I still talk in Webform talk)
The code below basically says, when the document is ready (finished loading all controls) set a function up that, when a Control (in this case, an <input/>) having the id “Category”’s selection is changed, call a function named callActivityCategoryAJAX(id), passing the value of the selected option.
$(document).ready(function () {
$('#Category').change(function () {
callActivityCategoryAJAX($("#Category option:selected").val());
});
});
This block can be placed anywhere on the view inside <script> tags. I chose to implement the function that it will call, callActivityCategoryAJAX in a separate .js file, referenced from the view.
By the way, this way of setting event handlers up inside script tags is known as “unobtrusive JavaScript”, coming from the idea that separation of code and markup is essential to good design and reuse, and keeping the markup free of onchange=”somefunction()” will make the markup easier to read. Unobtrusive JavaScript… almost as big on the scene right now as table-less design. Anyway, I agree with it, and being a very big fan of separation of code (logic) and markup, I chose to go with it. Why else would I be learning MVC, anyway, if I didn’t believe logic should work from behind the scenes?

2)  The AJAX Call from jQuery

We need to design our function that this ‘event handler’ will call.
function callActivityCategoryAJAX(id) {

var categoryOptions = '';
$.ajax(
{
url: 'ActivitiesByCategory',
type: "POST",
data: ({ categoryId: id }),
success: function (activities) {
ActivitiesByCategory_CallbackSuccess(activities);
HideShowElementsBasedOnCategory($("#Category option:selected").val());
}
})

}
This takes as a parameter the id. In my case, this is a GUID. The $.ajax part defines the behavior of the call to the controller, which acts as a webservice in other AJAX calls. The “url:” specifies just the name of the method here. It needs not reference a specific Controller here, because in my case this will reside in the same Controller class that contains the View’s main Controller.
The “type:” will be a POST, as this is what we need to use to call the method in the controller. The “data:” element sets the arguments for the call; in this case, our method will take one parameter, a GUID of the selected category.
Finally, “success:” is, as you may have guessed, the callback that executes when our Controller’s method is finished and returns. Make sure that the return value is placed as the argument for this. In this case, the method returns an array of Activity objects. So, I further split the callback, though you could, in theory, write the code right here under “success:” and the world not come to an end.
I will not spell out what this method does, as I want to keep this post short and to the point. Basically, it contains client-side code (JavaScript) to erase the current options from the Activities input and ‘for’ through the resulting array returned from the server-side method and add these to the list of options. Feel free to make more use of jQuery, as I did, and fade the Activities control out while it is being updated, and then back in. Or not.
One final thing I would like to say here, is there are other callbacks that can and should be specified to handle exceptional cases, cleanup, or customization of the request. I’ll list them here:
  1. beforeSend(XMLHttpRequest, settings) – use this to modify the XMLHttpRequest object before it is sent.
  2. complete(XMLHttpRequest, textStatus) – use this to do any final cleanup after either the success or error callbacks are executed.
  3. error(XMLHttpRequest, textStatus, errorThrown) – used when an exception occurs – i.e. 404 errors, exceptions from the server, and/or other HTTP status errors.
  4. success(data, textStatus, XMLHttpRequest) – the one we are using which handles the case that everything went smoothly.
In each of these use as many of the arguments as you need, though in incremental fashion, as the JavaScript standards specify. Correctly making use of these will help ensure robustness and a flexible web application.
Documentation of these and other related methods and properties can be found on the official jQuery Documentation Site here.

3)  Server-Side Methods in the Controller

The final piece to this puzzle is the server-side method, residing in this View’s Controller. Here it is:
namespace MyProject.Controllers
{
public class Activities: Controller
{
//.......[code here cut for clarity]........

[HttpPost]
public JsonResult ActivitiesByCategory(Guid categoryId)
{  
var returnValue = [something]; 
//code here that probably pulls from      
// a cached IEnumerable of Activities matched 
//with Categories, or even pull from the Model itself
return Json(returnValue);
}
//......[more code here cut]..........
}
}

Pretty simple method that is behind the scenes. Not much should need explaining, but briefly – [HttpPost] specifies that this method will handle HTTP requests which are of type POST. It will return a type of JsonResult, which is natively handled by our JavaScript on the client-side. All the work that is done is to pull the list of corresponding Activities. Maybe you have cached this somewhere for performance, or maybe it is small enough, or executed infrequently enough, to pull from the Model. Either way, it’s your choice, depending on your needs. The resultant array is cast into JavaScript Object Notation (Json) via use of the Json class’ constructor, and sent back to the client.
NOTE: If one is to use an Object Relational Mapping such as LINQ To SQL or the Entity Framework, one should break circular references by using a ‘.select(x=> new{…}) and end it with a .ToList(). When I did not take time to do this the first time, I was bombarded with errors dealing with circular references. Since that phrase describes well what goes on in the ORM frameworks, it didn’t take too long to narrow down the problem.
Once back at the client-side of things, you can have access to the array and its properties using the standard [] and/or . (dot) operators.
And this sums the process up in three steps. In summary:
  1. Client-side event handler- done in JavaScript, unobtrusively. It is easily accomplished using jQuery, and should be done in the document’s ready() handler, which executes when the DOM is finished loading.
  2. AJAX call from client – specifies the method to call, along with other options. The most important here are the options which tell the client-side code how to handle communications from the server, be they the expected results, or a failure message.
  3. Server-side method – resides in the View’s controller. It needs to accept HTTP request method  (sometimes called ‘verbs’) of POST. In the declaration, it is set to return a JsonResult, and the data to be returned is cast into a Json object via the constructor.
Thanks for reading. Next time we will take a look at some more MVC 3 subjects that are quite common.
Wes