Wednesday, 4 June 2014

Using Data Annotations with Portable Class Libraries

I am currently writing an application that’s targeting multiple platforms – iOS, Android, Windows Phone as clients, and naturally .NET on the server which will be hosted in Azure. I’m making good use of portable class libraries, so that I can share as much code between my clients as possible (and I’m using Xamarin to make all this possible).

For my client projects I have two shared libraries – one with interfaces, another with implementations. As an example I have a DTO class on the client as follows…

public class AccountInformationRequest
{
public string Token { get; set; }

public string MSISDN { get; set; }

public string Carrier { get; set; }
}



This class is also used on the server in a controller method…

public async Task<AccountInformation> PostAccountInformation(AccountInformationRequest request)
{
return await _accountInformationService.GetAccountInformation(request);
}



On the server however I want to use data annotations to minimise the amount of code I need to write in order to validate the incoming request but this poses a problem – the AccountInformationRequest type is defined in a Portable Class Library, and if I update it to add on the data annotation attributes then my PCL will be re-targeted and won’t then run on all of my desired client platforms.


As usual in programming, another level of indirection solves every problem. Since .NET 1.0 we’ve had ICustomTypeDescriptor, and indeed one of the first articles I wrote online was about this interface (the article is long gone, it was written in 2001 ish). Since .NET 2 things have got measurably better for anyone wanting to do some spelunking with types, as it released the TypeDescriptor and TypeDescriptorProvider support. Fast forward a few more years and we now have a very simple way to augment one class with metadata from another – the massively named ‘AssociatedMetadataTypeTypeDescriptionProvider’.


What this class allows you to do is say “Hey, this class X provides metadata for that class Y”. Or more to the point for this article, “This server class which has all the attributes I need replaces the metadata for the PCL class”. All you need to do is create a second class which has all the metadata attributes you need (in my case just validation), then register it. My server side class is as follows…

public class AccountInformationRequestServer
{
[Required]
public string Token { get; set; }

[Required]
public string MSISDN { get; set; }

[Required]
public string Carrier { get; set; }
}



Then I can just register it inside Global.asax…

TypeDescriptor.AddProvider
(new AssociatedMetadataTypeTypeDescriptionProvider(typeof(AccountInformationRequest),
typeof(AccountInformationRequestServer)),
typeof(AccountInformationRequest));



The registration looks a little cryptic, so I’ve altered it below to show the orginalClass (that being the class defined in the PCL) and the metadataClass (that being the one defined server side)…

TypeDescriptor.AddProvider
(new AssociatedMetadataTypeTypeDescriptionProvider(typeof(originalClass), typeof(metadataClass)),
typeof(originalClass));



That’s all there is to it. Now I can make an API call from the client, and have API validation on the server, whilst still using the same datatypes in both PCL and full fat .NET.


You’ll find the AssociatedMetadataTypeTypeDescriptionProvider class defined within System.ComponentModel.DataAnnotations (in the assembly with the same name).


6 comments:

Hines Vaughan said...

Very cool stuff. I am just about to start a strikingly similar project for a client and this will be very helpful! Thank you sir.

Neil Walker said...

Portable class libraries contain some of the articles and materials for students as well. Saint Michael's College libraries have been using an old method of essay writing help service assignments within the class activities. Among those - citations and reminders as well as footnotes.

Richard Majece said...

I think that randomness isn't the best idea here. I am sure that https://pro-academic-writers.com/blog/harvard-format will help you to understand all the importance of my words. Just pay attention on education.

blackkutty said...

Extremely cool stuff. I am going to begin a strikingly comparative task for a customer and this will be extremely useful!
Article Submission sites | Latest Updates

admin said...

It’s very excellent information and more real facts to provided that post.Thank you for sharing this information. 500-701 exam dump

Amirtha rao said...

Thanks for sharing the valuable information.
Regards,
DOT NET Training Institutes in Chennai|Best DOT NET Training in Chennai|DOT NET Training in Chennai