If you were wondering where I was for the past couple of weeks... It's winter! I snowboard, ski... not a lot of time for this programamamaming shtuff... That's when I'm bored out of my mind and have nothing "cool" to do. Don't get me wrong, I like programming... but not that much to take over my after work "activities".
I think I was reading david hayden's blog when I saw VAB for the very first time. I thought to my self, thats f***ing kick ass!
Seriously, don't you just hate creating "default" validation items for objects you need to validate? How come it took this long to get something like this to come out? I shouldnt whine... I tell you... its good shit!
Below is a sample code I whipped up for all ya suckahz out there that demonstrates not nullage, string lenghtage, and my custom validationage... Also you will notice a little bit of david hayden in the sample code. Mr. Hayden, if you are reading this, your sample was awesome!
I also would like to let Neil B. know that I STOLE his dog object that he used in his presentation @ Edmonton Code Camp 06. Take that FP!
Let's start with the tests...
1 using app.domain;
2 using Microsoft.Practices.EnterpriseLibrary.Validation;
3 using NUnit.Framework;
4
5 namespace test.domaintest
6 {
7 [TestFixture]
8 public class DogTest
9 {
10 [Test]
11 public void ShouldHaveValidDog()
12 {
13 Dog dog = CreateDog("Chiyo", Breed.GreatPyrenees, Color.White, Gender.Female);
14 Assert.IsNotNull(dog);
15 Assert.IsTrue(dog.IsValid());
16 Assert.IsTrue(dog.IsDirty);
17 Assert.IsTrue(dog.IsSavable());
18 }
19
20 [Test]
21 public void ShouldInvalidateNoName()
22 {
23 Dog dog = CreateDog(string.Empty, Breed.GreatPyrenees, Color.White, Gender.Female);
24 Assert.IsNotNull(dog);
25
26 ValidationResults results = dog.Validate();
27 Assert.IsFalse(results.IsValid);
28 foreach (ValidationResult result in results)
29 {
30 Assert.AreEqual(Dog.FIRST_NAME_LENGTH_ERROR_MESSAGE, result.Message);
31 }
32
33 Assert.IsFalse(dog.IsValid());
34 Assert.IsTrue(dog.IsDirty);
35 Assert.IsFalse(dog.IsSavable());
36 }
37
38 [Test]
39 public void ShouldInvalidateNullBreed()
40 {
41 Dog dog = CreateDog("Chiyo", null, Color.White, Gender.Female);
42 Assert.IsNotNull(dog);
43
44 ValidationResults results = dog.Validate();
45 Assert.IsFalse(results.IsValid);
46 foreach (ValidationResult result in results)
47 {
48 Assert.AreEqual(Dog.BREED_ERROR_MESSAGE, result.Message);
49 }
50
51 Assert.IsFalse(dog.IsValid());
52 Assert.IsTrue(dog.IsDirty);
53 Assert.IsFalse(dog.IsSavable());
54 }
55
56 [Test]
57 public void ShouldHaveANonDirtyDog()
58 {
59 Dog dog = new Dog();
60 Assert.IsFalse(dog.IsDirty);
61 }
62
63 [Test]
64 public void ChiyoShouldNotBeLesbian()
65 {
66 Dog dog = CreateDog("Chiyo", Breed.GreatPyrenees, Color.White, Gender.Lesbian);
67 Assert.IsNotNull(dog);
68
69 ValidationResults results = dog.Validate();
70 Assert.IsFalse(results.IsValid);
71 foreach (ValidationResult result in results)
72 {
73 Assert.AreEqual(ChiyoIsNotLesbianValidator.CHIYO_ERROR_MESSAGE, result.Message);
74 }
75
76 Assert.IsFalse(dog.IsValid());
77 Assert.IsTrue(dog.IsDirty);
78 Assert.IsFalse(dog.IsSavable());
79 }
80
81 private static Dog CreateDog(string name, Breed breed, Color color, Gender gender)
82 {
83 Dog dog = new Dog();
84 dog.Name = name;
85 dog.Breed = breed;
86 dog.Color = color;
87 dog.Gender = gender;
88
89 return dog;
90 }
91 }
92 }
The Code...
1 using System;
2 using Microsoft.Practices.EnterpriseLibrary.Validation;
3 using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
4
5 namespace app.domain
6 {
7 [ChiyoIsNotLesbianValidator]
8 public class Dog : DomainObject<Dog>, IDomainObject
9 {
10 public const string FIRST_NAME_ERROR_MESSAGE = "Please enter first name";
11 public const string FIRST_NAME_LENGTH_ERROR_MESSAGE = "Dog's name must have a maximum length of 50";
12 public const string BREED_ERROR_MESSAGE = "Please select breed";
13
14 private string name;
15 private Breed breed;
16 private Color color;
17 private Gender gender;
18
19
20 public Dog()
21 {
22 }
23
24 public Dog(Validator validationService) : base(validationService)
25 {
26 }
27
28 [NotNullValidator(MessageTemplate = FIRST_NAME_ERROR_MESSAGE)]
29 [StringLengthValidator(1, 50, MessageTemplate = FIRST_NAME_LENGTH_ERROR_MESSAGE)]
30 public string Name
31 {
32 get { return name; }
33 set
34 {
35 name = value;
36 base.IsDirty = true;
37 }
38 }
39
40 [NotNullValidator(MessageTemplate = BREED_ERROR_MESSAGE)]
41 public Breed Breed
42 {
43 get { return breed; }
44 set
45 {
46 breed = value;
47 base.IsDirty = true;
48 }
49 }
50
51 public Color Color
52 {
53 get { return color; }
54 set
55 {
56 color = value;
57 base.IsDirty = true;
58 }
59 }
60
61 public Gender Gender
62 {
63 get { return gender; }
64 set
65 {
66 gender = value;
67 base.IsDirty = true;
68 }
69 }
70 }
71 }
and here is my custom validator...
73 namespace app.domain
74 {
75 public class ChiyoIsNotLesbianValidatorAttribute : ValidatorAttribute
76 {
77 protected override Validator DoCreateValidator(Type targetType)
78 {
79 return new ChiyoIsNotLesbianValidator(GetMessageTemplate(), Tag);
80 }
81 }
82
83 public class ChiyoIsNotLesbianValidator : Validator<Dog>
84 {
85 public const string CHIYO_ERROR_MESSAGE = "Chiyo aint lesbian!";
86 private string defaultMessageTemplate;
87
88 public ChiyoIsNotLesbianValidator(string template, string tag)
89 : base(template, tag)
90 {
91 defaultMessageTemplate = CHIYO_ERROR_MESSAGE;
92 }
93
94 protected override void DoValidate(Dog objectToValidate, object currentTarget, string key,
95 ValidationResults validationResults)
96 {
97 try
98 {
99 if (objectToValidate.Gender == Gender.Lesbian && objectToValidate.Name.ToLower() == "chiyo")
100 validationResults.AddResult(
101 new ValidationResult(CHIYO_ERROR_MESSAGE, string.Empty, string.Empty, string.Empty, this));
102 }
103 catch
104 {
105 validationResults.AddResult(
106 new ValidationResult("Something messed up.", string.Empty, string.Empty, string.Empty, this));
107 }
108 }
109
110 protected override string DefaultMessageTemplate
111 {
112 get { return defaultMessageTemplate; }
113 }
114 }
115 }

11 comments:
Hey Jonas,
I saw a very similar validation process represented in a post on Donald Belcham's blog. My comment still stands. The validation works just fine until you decide you want to use resource files to globalize your validation messages. Attributes can only use constants, not static values and, thus, cannot be easily globalized. I think that the most extensible method of validation for validation logic that I have come across previously is J.P's Validation in the Domain Layer.
Hey JH,
Localization eh? Sound's very Canadian for me... It's the damn fr-CA crap isnt it?
What I was thinking was use the message template as a "key" to be used to find the localized text. This means that we have to have a localization engine.
But again, I don't care. VAB is still in beta, give it time.
Jonas
Great sample code - it cracked me up big time :-)
Re localization - check out the properties available in both the configuration objects and attributes that allow you to reference message templates in resource files.
Tom
(Microsoft patterns & practices team)
i can't get namespace"NUnit" and appdomain
how i will get those namespaces
Hey Anonymous,
NUnit - goto nunit.com/org
AppDomain is from the system namespace
in my validation application block
"ASSERT" statement is not working.
is it any namespace required i
have to add my application
hey anon.
are u familiar with Test Driven Development?
Assertions are part of nunit. please google "add reference visual studio"
HI
this is kapil
I got some problem while working with nunitasp I included namespaces like
nunit.extensions.asp
nunit.extensions.asp.asptester;
nunit.frame work;
nunit.framework.syntaxhelpers;
help me out from this
Hi Kapil,
Unfortunately I do not use NUnitASP for my UI testing. I usually go with WatiR (http://wtr.rubyforge.org/)
Jonas
hello,
Can you please tell me, is there any free control for Fileuploading in Asp.net Ajax with a Progressbar.
Note : progressbar shoulb be simulated with data transfered; max file upload size required is 100mb, even if i try to upload in FTP it should accept 100mb.
Regards,
Rakesh
validationResults.AddResult(new ValidationResult(CHIYO_ERROR_MESSAGE, string.Empty, string.Empty, string.Empty, this));
If I want to use the error messave from the Resource file like the [NotNullValidator] example given below, How Can I change the above line of code instead of CHIYO_ERROR_MESSAGE?
[NotNullValidator (MessageTemplateResourceType = typeof(Resources), MessageTemplateResourceName = "InvalidMessage")]
Post a Comment