Monthly Archives: August 2011

Making custom dataannotation attributes work with MVC client side validation

In a previous blog entry I showed you a easier approach to localized DataAnnotation attributes.

The problem with that approach was that client side validation didn’t work. It isn’t hard to fix. All you need is to borrow some code from the built in DataAnnotation support and reference the custom attributes instead.

Here is a sample implementation.

    public class RequiredAttributeAdapter : DataAnnotationsModelValidator<RequiredAttribute>
    {
        public RequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, RequiredAttribute attribute)
            : base(metadata, context, attribute)
        {
        }

        public static void SelfRegister()
        {
            DataAnnotationsModelValidatorProvider
                .RegisterAdapter(
                    typeof (RequiredAttribute),
                    typeof (RequiredAttributeAdapter));
        }

        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
        {
            return new[] { new ModelClientValidationRequiredRule(ErrorMessage) };
        }
    }

Then simply call RequiredAttributeAdapter.SelfRegister(); somewhere in your Global.asax


Handling JSON responses in jquery plugins

I’ve been coding several jquery plugins lately and most of my plugins uses Ajax and JSON to handle data. Each plugin gets a specific JSON string returned that must follow a specific format. For instance, the table plugin expects to get total number of rows and an array containing the rows to add:

	var jsonResponse = { 
		"TotalRowCount": 2,
		"Debug": true,
		"TableMode": 'Append', 
		"Rows" : [
			{ "Id": 1, "Title": "Fool", "FirstName": "Jonas", "LastName": "Gauffin", "Age": 34, "Options": "<a href="/add">aa</a>" },
			{ "Id": 2, "FirstName": "Arne", "LastName": "Purka", "Age": 14},
		]
	};

Nothing strange with that. The problem is when I want to return something else than rows. The plugin cannot handle that. I might for instance want to return an error message informing the user that something went wrong.

My first attempt was to change so that all plugins used a structure like this:

var response = {
    "ContentType": 'Rows',
    "Body": {
      "TotalRowCount": 2,
      "Debug": true,
      "TableMode": 'Append',
      "Rows" : [
        { "Id": 1, "Title": "Fool", "FirstName": "Jonas", "LastName": "Gauffin", "Age": 34, "Options": "<a href="/add">aa</a>" },
        { "Id": 2, "FirstName": "Arne", "LastName": "Purka", "Age": 14},
      ]
    }
}

where the Body data would be everything in the first JSON code sample. But since javascript is dynamic I felt that it’s really not necessary to wrap everything like that. I just add the ContentType to all original JSON responses.

	var jsonResponse = { 
		"ContentType": 'Rows',
		"TotalRowCount": 2,
		"Debug": true,
		"TableMode": 'Append', 
		"Rows" : [
			{ "Id": 1, "Title": "Fool", "FirstName": "Jonas", "LastName": "Gauffin", "Age": 34, "Options": "<a href="/add">aa</a>" },
			{ "Id": 2, "FirstName": "Arne", "LastName": "Purka", "Age": 14},
		]
	};

In this way I only have to check the ContentType before doing anything else and then take an appropriate action.

Right now I’m trying to figure out if I should add a general JSON response pre processor which is invoked before the actual plugin get’s to handle the response. (declare it in my own jquery plugin namespace and invoke it from each plugin if it exist). In that way I can move all general handling (like handling errors) to a separate place instead having to duplicate it in all plugins.