Showing posts with label MVC. Show all posts
Showing posts with label MVC. Show all posts

Tuesday, November 03, 2009

Using WCF to power a Custom DataTypeAttribute

In a previous post i demonstrated the simplicity in which you can create a custom DataTypeAttribute, this post aims to take it one step further, or totally off track depending on how you look at it.

the scenario

the rule our custom datatypeattribute applies when validating should be supplied from a service, making it available for several different layers all incorporating one and the same basic rule.

The sample project is complete with a MVC 2 (preview 2) web site, and a WCF service project. Note that it’s created with Visual Studio 2010 Ultimate Beta 2, so you’ll need that as well if you want to run it (you can always re-create it if you so choose).

Part 1 – simple WCF service

wcfThe WCF service in this example holds two simple methods, one for the rule and the other for the error message:

namespace ValidationServiceWCF
{
    public class Rules : IRules
    {
        private int maxlength = 2;
        public bool MaxShortTitleLength(string text)
        {
            if (string.IsNullOrEmpty(text))
            {
                return false;
            }
            return text.Length<=maxlength;
        }
 
        public string MaxShortTitleLengthErrorMessage()
        {
            return string.Format("{0} is invalid, can only be up to {1} chars", "{0}", maxlength);
        }
    }
}
Part 2 – the mvc 2 project

mvc2projThe rule created in the WCF service is then applied in a custom datatypeattribute class called MaxLengthAttribute:

namespace ValidationService.Models.DataAnnotations
{
    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
    public class MaxShortTitleLengthAttribute : DataTypeAttribute
    {
        private string errortext = string.Empty; 
        RulesService.IRules rulesengine = new RulesService.RulesClient();
 
        public MaxShortTitleLengthAttribute()
            : base(DataType.Text)
        {
            errortext = rulesengine.MaxShortTitleLengthErrorMessage();
        }
 
 
        public override bool IsValid(object value)
        {
            if (rulesengine.MaxShortTitleLength((string)value))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
 
        public override string FormatErrorMessage(string name)
        {
            return string.Format(errortext, name);
        }
    }
}

that attribute is then applied on our model using the DataTypeAttribute approach we’re now familiar with:

namespace ValidationService.Models
{
    [MetadataType(typeof(Product_MetaData))]
    public partial class Product
    {
    }
    internal class Product_MetaData
    { 
        [Required]
        [ScaffoldColumn(false)]
        public int ID { get; set; }
 
        [Required]
        public string Title { get; set; }
 
        [Required]
        [MaxShortTitleLength()]
        public string ShortTitle { get; set; }
    }
}

After that it was just a matter of creating some actions, wiring a few views, setting up a context and repository class and finally wrapping it all up.

Now when validation is run on the ShortTitle property of the model the custom attribute fires off to the service, calls the validation method and gets the errormessage in case we’ll need it:

errormessage

That’s it, source code available here (VS 2010 Beta 2).

Note: this is a simple example and therefore i’ve just used the HomeController to handle everything. The endpoint for the WCF is currently pointing to localhost:7556/rules.svc.

Regards,

P.

Wednesday, September 16, 2009

Codename 'DiscMaster'

I get one specific question a lot: what would you develop on your own time if you could choose? That question raised has always left me hanging without an answer.. there's too much stuff to try, create, reengineer and analyze. For once i thought i'd actually go ahead and make sense of one of those ideas and turn it into something real. So, say hello to codename 'DiscMaster'! Codename 'DiscMaster' is a website/community for those of us that enjoy discgolfing (yes, i'm one of those people that throw a disc/frisbee around on a pseudo-golfcourse and call it fun). It's built on ASP.NET MVC, LINQ (including LINQ to SQL), Dynamic Data, Entity Framework and custom providers for Repository and Membership - to name but a few. Right now registration is per invitation only on a non-disclosed url and will continue that way while in development - this means that each member that is invited and registers can invite up to three more people to join. Right now registered users can:
  • view courses
  • manage courses
  • manage course layouts
  • manage their own profile
  • manage matches
  • view personal statistics
  • view match statistics
  • view players
  • generate reports
  • and much, much more!
Below are some screenshots showing (still in a standardized mvc layout) some of the features - names and personal details are crossed-out (ok, ok, i know i missed a spot) for privacy reasons but i'm sure you'll get the general idea.
Future updates to this project include:
  • Weather service integration
  • Maps service integration
  • Interactive graphs based on Silverlight
  • OpenID integration
  • Social Networks integration
Also, on a sidetrack, there's development in progress for an iPhone app with score synchronization..
More details, screenshots and thoughts regarding this project will come in later posts..
Regards,
P.