Tuesday 23 September 2008

ASP.NET MVC - If it feels this right it can't be wrong!

Having had a few days leave from work I've spent most of my evenings playing with the not-so new MVC framework. It's been great to spend some focused time playing with this new toy for web development from Microsoft. One thing that I've noticed is how nicely and quickly you can start to put together powerful, enterprise happy software with it. My starting point has been a model (a bunch of POCOs based around the educational assessment domain, which I know well) using NHibernate for persistence, Windsor for a DI framework (though not for the controllers yet), MBUnit and RhinoMocks for unit testing, and the latest (5) release of the MVC framework. After getting some simple stories completed (add a candidate, edit a candidate, register a candidate for an assessment) I wanted to try and improve the user experience by getting some Ajax into the Views. I've had a play with using Scriptaculous and JQuery with the MVC framework during brief forays in the past, so this time I thought I'd just use the default MS stuff that ships with it.

One example of the kind of implicit wiring that the framework deals with you that I found really neat was this. I have a view that lists candidates based on a search (I hope to blog about that before long).

<%
foreach (Candidate candidate in ViewData.Model as List<Candidate>)
{%>
<tr>
<td><%=Ajax.ActionLink("View", "ViewDetail", "Candidate", candidate, new AjaxOptions { UpdateTargetId = "CandidateDetail" })%></td>
<td><%=Ajax.ActionLink("Edit","EditDetail","Candidate", candidate, new AjaxOptions{ UpdateTargetId = "CandidateDetail"}) %></td>
<td><%=Html.Encode(candidate.Id.ToString())%></td>
<td><%=Html.Encode(candidate.Name.FullName)%></td>
</tr>
<%
}%>

Note the use of the Ajax.ActionLink method here. This will update my CandidateDetail div with the results of the Ajax call. The call itself will be to the ViewDetail action of the CandidateController class, and the properties of the Candidate object for the row will be available to this action. The neat thing for me is that in the action if I request just an id argument then this is automagically wired up to the Id property of the Candidate object for me!

[AcceptVerbs("POST")]
public ActionResult ViewDetail(Guid id)
{
ICandidateRepository candidateRepository = MvcApplication.WindsorContainer.Resolve<ICandidateRepository>();
Candidate candidate = candidateRepository.GetCandidate(id);
return View("Detail", candidate);
}

As you can see, the code above has one argument that accepts a Guid and is called id. The framework, following convention (love that), realises I mean the id of the candidate object and passes it into the method. Neat huh! I then get the appropriate candidate object from my repository and then return the detail view (an ascx control) passing the retrieved candidate object in. This control will then be rendered into the div originally specified (CandidateDetail).

This is just one example of how easy it can be to get this framework working for you. I'm really, really liking working with all this new MVC goodness, it just feels so, right!

No comments: