Wednesday, 27 October 2010

Saturday, 16 October 2010

Validation with ASP.Net MVC2

I've blogged previously about the validation methods I've used on ASP.Net MVC projects and have recently been adapting this for use with version 2 of the framework.

One of the new features I wanted to make available was the use of data annotations for validation, where domain or view model classes can be decorated with attributes for validation of required fields, field lengths and range values. These can then be used for both server side and client side validation.

I ran into a problem with this though when validating entities that had related items - for example in my case I was working on a project management tool, where an entity such as a project is related to others such as a client and an account manager. The client entity has required fields such as a name, but when validating before saving the project entity I didn't really care about that as I was only interested in the client ID to perform the update operation.

The validation by default is set up to perform whole model validation, but a useful post from Steve Sanderson details how to get around this issue and perform partial validation based on just the values that are passed in the form post.

Data annotiation based validation isn't the the full story though - in a robust application it's considered necessary for the domain model to handle it's own validation too. This is partly a result of using techniques such as the above, which would allow a determined hacker to modify the form input to by-pass data annotation based checks on required fields.

In previous projects I've used straightforward C# code for the validation of model fields, but as I'd already used data annotions to define these rules it was a obvious violation of the DRY principle to have to do this again. .Net 4 provides a means of doing this using the Validator.TryValidateObject method.

For .Net 3.5 though I used a technique illustrated by JohnyO in this post on stackoverflow. It validates based on rules specified both directly on the class or in a meta data "buddy" class and thus allows the domain model to handle validation without repetition of all the rules.

Saturday, 2 October 2010

iPhone Custom UIView with Controls

Armed with a copy of the Pragmatic Programmer's book and a lot of Googling, have made a start recently on developing apps for the iPhone. Took a while to find my way around XCode, Interface Builder and to get to thinking again about things like memory management, but made some progress and have released an app for bass guitar players learning scales or modes.

It's fairly straightforward - is based on a navigation controller app, and has a single table view for selecting the scale and then a custom view for displaying the scale itself. You can choose the mode, key and speed and then view the tablature for playing the scale as well as listening to it played and viewing the fingering positions.

The only tricky bit really was the display of the scale and for this I needed to develop a custom UIView. By doing this you can draw directly to the canvas - which I needed to do for the tab lines (or strings) and for plotting the finger positions of the scale. Normally with a view you use Interface Builder or code to generate controls and associate them with IBOutlets and IBActions in XCode. The problem I found was that I wanted to do both - i.e. I needed a custom view in order to display the information that couldn't be rendered using controls, but also wanted to make use of controls for functions like the selection of mode and key.

I also had the issue that I wanted to pass information to the custom UIView, by setting a property for the scale (a custom class I had created which represented the selected scale - with properties like the name, description and intervals).

I solved this using the following code which involves casting the view object to the type of my custom UIView in the UIViewControllers viewWillAppear method, which then allows me to set it's custom property.

- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];

//Pass details of scale in custom property
[(ScaleDisplayView *)[self view] setScale:scale];

//Display scale details
self.nameLabel.text = [NSString stringWithFormat:@"The %@ scale", self.scale.name];
self.descriptionLabel.text = self.scale.description;

//Initialise view
self.title = self.scale.name;
self.view.backgroundColor = [UIColor whiteColor];
[self.view setNeedsDisplay];
}