Tuesday, 31 March 2009

ASP.Net MVC Resources

I’ve been working recently on a project using the ASP.Net MVC framework – Microsoft’s implementation of this pattern as an alternative means of presentation from Web forms. There are a number of basic tutorials on the web, but it’s taken a bit of digging to make progress beyond the relatively simple examples.

As with any new technology, you get stuck on things that should be simple, but having worked through these issues am enjoying using the framework, and have started to use it for an, albeit small, production project for a client.

The project follows the standard list, create, edit, delete application type that many of the tutorials follow, so it seemed a good fit.

In this post I’ll pull together some of the best resources I found that helped me on my way to developing this application, along with some tips on how certain problems were solved.

Tutorials

Firstly the application was based on the excellent tutorial Stephen Walther has released – this demonstrates the use of views and controllers, and extends the model to provide data access and validation, via clear use of interfaces and design patterns to adhere to the loosely coupled best practices in this area. He also illustrates how MVC supports unit testing – one of its major advantages over web forms.

Taking Things Further...

Editing Complex Properties
One of the first hurdles I had to get over was the editing of a record that has a field selected from a drop-down list (as opposed to simply entering the value in a text box that most of the simple tutorials demonstrate – these work “out of the box” if you make sure you use a typed view and ensure the names of your input fields match the names of your class properties).

There are three discrete challenges here – one is passing the data to the view that populates the selection list, another is pre-selecting the current value and finally we need to get the updated value to pass up to the data access layer.

The following controller logic passes additional data to the view for creating and editing a list of users for an application; in this case a list of user "roles" to be selected in a drop-down list. The Create action passes the list, the Edit the list within an additional parameter indicating the current selection:

public ActionResult Create()
{
GetRoleListForViewData();
return View();
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude = "ID")] User objUserToCreate)
{
//Get selected Role object and attach to created User
objUserToCreate.Role = mobjService.GetRole(byte.Parse(Request["Roles"]));

//Create user record - redirect to list if succcesful or redisplay form if not
if (mobjService.CreateUser(objUserToCreate))
return RedirectToAction("Index");
GetRoleListForViewData();
return View("Create");
}

public ActionResult Edit(int id)
{
User objUser = mobjService.GetUser(id); //retrieves User object
GetRoleListForViewData(objUser.Role.ID);
return View(objUser);
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(User objUserToEdit)
{
//Note - the following does not work when using Entity Framework
//it marks the object as "Added" rather than "Detached"
//and leads to problems when calling ApplyPropertyValues
//
//objUserToEdit.Role = mobjService.GetRole(byte.Parse(Request["Roles"]));

objUserToEdit.Role = new Role();
objUserToEdit.Role.ID = byte.Parse(Request["Roles"];

if (mobjService.EditUser(objUserToEdit))
return RedirectToAction("Index");
GetRoleListForViewData(objUserToEdit.Role.ID);
return View("Edit", objUserToEdit);
}

private void GetRoleListForViewData()
{
ViewData["Roles"] = new SelectList(mobjService.ListRoles(), "ID", "Name");
}

private void GetRoleListForViewData(int intSelectedID)
{
ViewData["Roles"] = new SelectList(mobjService.ListRoles(), "ID", "Name", intSelectedID);
}

Useful Code Samples

Paging
Martijn Boland provides an excellent sample project that can simply be referenced in order to provide a paging mechanic.

C# Language Extensions to Support LINQ

On the final day of Devweek this year I attended a full-day workshop on LINQ. It was initially billed as a day of “Entity Framework and LINQ”, but annoying the first bit of the title was dropped at some point before the day! Nonetheless it was a good presentation of what LINQ is, what language extension have been developed to support it, and how it is used in LINQ to Objects, LINQ to XML and LINQ to Entities. The talk was given by Niels Berglund.

In order to support LINQ, a number of amends and enhancements were made to the .Net compiler and the VB.Net and C# languages – I found it worth getting my head around these, so that the LINQ language introduced later appeared less like “magic”.

Automatic Properties

Traditionally properties would be created in a class with a public accessor and a private backing store:

private string mstrFirstName;

public string FirstName
{
get { return mstrFirstName; }
set { mstrFirstName = value; }
}

At the compiled code level this hasn’t changed, but in C# as a productivity enhancement you can now simply do this:

public string FirstName { get; set; }

Object Initialisers

Again as an alternate syntax, objects can be initialised in a single statement:

User objUser = new User { ID = 1, FirstName = “Fred”, LastName = “Bloggs” }

Type inference with var

For local types, you can leave the complier to work out what type you are assigning to a variable. Note this is not the same as VB’s variant, or an untyped variable found in an interpreted language like VBScript – it will be typed in the compiled code, and the compiler will complain if you try to subsequently assign a string to a variable initialised with an integer for example.

var i = 1;

Personally, I would only use this when the occasion warranted it – e.g. from LINQ queries – as I feel this reduces code readability.

Extension Methods
Can be used to extend classes that may be sealed or for which you may not have source code available. Really they are just static methods that appear to be instance methods.

e.g. adding an extension method to the string class:

static class MyExtensions
{
public static string MyExtension(this string s)
{
return DoSomething(s);
}
}
Anonymous Methods
Allow you to define a method in-line. Normally when you use delegates you pass an existing method - using anonymous method you can define it in the same line as the call.

Lambda Expressions
Lambda expressions are another way of writing anonymous methods (inline functions):

Array.Sort (nums, delegate(int a, int b) {return a.CompareTo(b); } );

Array.Sort (nums, {a, b} => a.CompareTo(b) );

Friday, 27 March 2009

Entity Framework – Customising Entities

A fairly simple extension I wanted to make to one of my imported entities was to provide a read-only, concatenated property. I tend to do this on any business object that represents a person to provide a single, read-only property for their full-name.

In a simple C# class, it would look like this:

private string mstrFirstName;
private string mstrLastName;

public string FirstName
{
get { return mstrFirstName; }
set { mstrFirstName = value; }
}
public string LastName
{
get { return mstrLastName; }
set { mstrLastName = value; }
}
public string FullName
{
get { return mstrFirstName + ‘ ‘ + mstrLastName; }
}

To implement with the Entity Framework, the first thought might be to add this same property to the class produced… but of course this class is generated automatically by the framework, and hence any changes made would be overridden.

.Net’s concept of partial classes come to the rescue here. You simply make your own class with the same name as the class you wish to extend, declare it as partial and then implement your own property and/or method extensions:

namespace AssetManager.Models
{
public partial class User :
global::System.Data.Objects.DataClasses.EntityObject
{
public string FullName
{
get
{
return this.FirstName.Trim() + " " + this.LastName.Trim();
}
}
}
}

Wednesday, 25 March 2009

Entity Framework Complex Types (IDE Issues)

Have recently been getting to grips with the Entity Framework and MVC, both of which I’m using on a relatively small project to gain an understanding of the technologies and to evaluate whether we should consider either of these technologies for more major solutions at this stage in their life-cycle.

There’s obviously a fair old learning curve involved, but armed with Julia Lerman’s book have made good progress with Entity Framework and thus far have been very impressed. Have run into a few issues of course, and the one giving me most grief is regard to complex types.

The issue arises when, having created your model from your database you want to make some customisations to it. This is an important feature, as one of the major points of this technology should be to allow you program against a model that you (the app developer) want to use and not be completely tied to the database structure.

A common requirement here would be to convert a single table (or imported entity) into two – the entity plus another one represented as a property of the first. The classic example would I guess be an address.

Say you have a table Customers with the following fields:

ID
FirstName
LastName
AddressLine1
AddressLine2
City
County
Postcode

And want to represent this as two classes – Customer and Address.

Customer
ID
FirstName
LastName
Address

Address
Line1
Line2
City
County
Postcode

This would allow you to refer to the address of an instantiated Customer object like this...

objCustomer.Address.City

... which is arguably more elegant and more practically would allow you to re-use the Address class elsewhere.

This is supported by the Entity Framework, but not by the designer – you have to make the following amends in the XML directly.

I can live with that as am happy to get my head around what is going on under the hood, but unfortunately this means the Designer support is gone for good – you have to make all subsequent edits in the XML. Hopefully this will be supported in future versions.

More annoyingly though, VS.Net reports a couple of errors (not warnings) that would suggest a build failure has occurred. It hasn’t though, it will build fine if you ignore these errors and can use the complex types as expected. But this makes working with the project rather tricky from then on, as you have to scroll past these “errors” to find your real ones as you continue working on the solution.

[Update 25/11/09: looks like this issue has been resolved with entity framework 4]

Tuesday, 24 March 2009

ASP.Net Ajax at Devweek 2009

Following a recommendation from a client we obtained a pass for Devweek 2009, held at the Barbican in London last week. The first session I attended was a pre-conference workshop on ASP.Net Ajax presented by Fritz Onion. I was impressed with his delivery of the subject – he had that useful but all too rare skill in presenters of being able to code and talk at the same time! We covered quite a bit of ground: reviewing the status of AJAX in the existing ASP.Net platform, the background to the technology and also getting a preview of the next release of ASP.Net Ajax 4.0.

ASP.Net Ajax Today

Server Side Controls

The latest release of the technology comes with ASP.Net 3.5 service pack 1, which builds on technologies released at various stages since November 2005. By including a script manager tag, server side DLLs download JavaScript to the client:
<asp:ScriptManager id=”ScriptManager1” runat=”server” />
The key server side control is the UpdatePanel which enables partial page rendering. Placing controls within one of these panels causes the normal post-back event to be intercepted and converted to an Ajax call (JavaScript call over XMLHttp). This is incredibly simple to use and shields the developer should the want to be from the intricacies of client side scripting completely.

I had a project where an control had been used and recently was asked by a client to convert it such that it didn’t post-back every time you change month. The ASP.Net control doesn’t support this, and initially my first thought was to look to convert this to use another pure client side control. But far easier I soon discovered was to make use of the UpdatePanel:

<asp:UpdatePanel id=”pnlCalendarWrap” runat=”server” />
<ContentTemplate>
<asp:Calendar id=”calSchedule” runat=”server” />
</ContentTemplate>
</asp:UpdatePanel>

An important point to note with the UpdatePanel is that if the user has client side scripting disabled, of course the normal post-back will occur – an example of progressive enhancement (or graceful degradation if you prefer…).

One gotcha flagged was ensuring you set each of your UpdatePanel UpdateMode properties to “Conditional”. The default is “Always” – which will lead to the behaviour of all panels on the page updating at the same time, which is not normally what you want.

Another couple of useful features noted were the ability to disable the controls within the panel from causing an update, and delegating this to another control elsewhere on the page.

<asp:UpdatePanel id=”pnlUpdate” runat=”server” ChildrenAsTriggers=”false” />
<ContentTemplate>
<asp:Label id=”lblTest” runat=”server” />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID=”btnTrigger” EventName=”Click” />
</Triggers>
</asp:UpdatePanel>

<asp:Button id=”btnTrigger” runat=”server” OnClick=”btnTrigger_Click” Text=”Click me” />

One of the downsides of Ajax postbacks is that whilst the experience is much slicker for the user, it’s almost too seamless – web users are used to seeing hour-glasses, whirling globes and moving progress bars when waiting for things to happen. With Ajax you won’t get this – so standard practice is to provide some form of animated gif or other message to indicate that “something is happening”.

Again, there is a server side control to help with this – the UpdateProgress control which is used as follows:


<asp:UpdatePanel id=”pnlUpdate” runat=”server” />
<ContentTemplate>
<asp:Label id=”lblTest” runat=”server” />
<asp:Button id=”btnTrigger” runat=”server” OnClick=”btnTrigger_Click” Text=”Click me” />
</ContentTemplate>
</asp:UpdatePanel>

<br/>

<asp:UpdateProgress id=”prgUpdate” runat=”server” AssociatedUpdatePanelID=”pnlUpdate”>
<ProgressTemplate>
<img src=”anim.gif” alt=”Processing...” />
</ProgressTemplate>
<asp:UpdateProgress>

Client Side Coding

On the client side, the ASP.Net Ajax library makes available a number of well-known functions triggered by events, e.g.

function pageInit(sender)
{
}

function pageLoad(sender, args)
{
}

The pageLoad is likely to be the most useful. Like the jquery ready event, this is fired when the page has loaded and the DOM initialised, but before external assets like images have completely downloaded. This makes the event much more useful to tie immediate functionality to, as opposed to the standard onload event that fires after all referenced media are downloaded.

Others can be useful for initialisation, clean-up and client side error handling.

Exposing Page Methods to the Client

A couple of simple configuration changes allow you to expose certain server side page methods to client side scripting, again in a way that completely hides the coding complexities.

The key steps are to set the EnablePageMethods property to True on your ScriptManager control, and to decorate the static method you wish to expose with a [WebMethod] attribute.

In page.aspx.cs (code behind):

[WebMethod]
public static int Add(int i, int j)
{
return i + j;
}

And in page.aspx:

<asp:ScriptManager id=”ScriptManager1” runat=”server” EnablePageMethods=”true” />

<script type=“text/javascript“>

var i = 2, j = 4;
var result = PageMethods.Add(i, j);
alert(result);

</script>

The Future of ASP.Net Ajax

There were three areas of interest discussed with regard to how Microsoft’s support for Ajax is going in the future.

The first was with regard to the Ajax control toolkit – when this was launched it caused quite a stir in our office, and the ease of use of these controls meant that several made their way into our projects. In particular the Accordian control and the ModalPopup. Others though proved a bit of a disappointment – the DragPanel with no support for dropping always seemed to me to be missing something rather important…

These were released to the Microsoft developer community to extend, but it seems this never really took off as hoped, so plans are for Microsoft to take these back in house for the next release. It’s probably slightly shaming that we MS developers didn’t take this on further, but this should mean the controls released will be further developed come VS.Net 2010.

The second issue was the support for jquery – a favourite of front-end focussed developers – and now officially distributed and supported by Microsoft with the release of the ASP.Net MVC framework, and which can be used alongside ASP.Net Ajax.

Finally we had a look at client side data binding – planned for release with ASP.Net Ajax 4.0. The idea is to allow the declaration of something like “client side repeaters”, so data can be retrieved, displayed, filtered, sorted, paged – and updated – on the client and without full-post backs to the server.