4
\$\begingroup\$

The model looks like this, with no attributes:

public class PersonalModel : Validatable
{ 
 public string Name { get; set; } 
 public string Email { get; set; }
 public override void Validate(dynamic item)
 {
 if (this.ValidatesPresenceOf(item.Name, "Name is required"))
 { 
 if (((String)item.Name).Length > 5)
 {
 Errors.Add("name is too long less than 5 chars please!");
 }
 } 
 } 
}

and the action looks like this:

 [HttpPost]
 [ValidateAntiForgeryToken]
 public ActionResult PersonalInfo(PersonalModel model)
 {
 if (model.IsValid(model))
 {
 this.FlashInfo("Your Personal info was successfully received");
 return RedirectToAction("ThankYou");
 }
 else
 { 
 ModelState.AddModelError(string.Empty, String.Join("; ", model.Errors.ToArray())) ; 
 return View(model);
 }
 }

This is the baseclass Validatable:

public class Validatable : DynamicObject
{
 //Hooks
 public virtual void Validate(dynamic item) { }
 //Temporary holder for error messages
 public IList<string> Errors = new List<string>();
 public bool IsValid(dynamic item)
 {
 Errors.Clear();
 Validate(item);
 return Errors.Count == 0;
 }
 //validation methods
 public virtual bool ValidatesPresenceOf(object value, string message = "Required")
 {
 if (value == null || String.IsNullOrEmpty(value.ToString())) 
 {
 Errors.Add(message);
 return false;
 }
 return true;
 }
}
palacsint
30.3k9 gold badges82 silver badges157 bronze badges
asked Jan 25, 2012 at 22:11
\$\endgroup\$

1 Answer 1

8
\$\begingroup\$

I wholeheartedly agree that the attributes are evil. But in my opinion having to derive from a base class is just as bad as having to add attributes. Both makes you depend on framework infrastructure you don't need to depend on. (Models should be model logic, and model logic only.)

In MVC (3 at least) you can implement a ModelValidatorProvider and a ModelMetadataProvider. The validator provider can be added in Application_Start using ModelValidatorProviders.Providers.Add(...), and the metdata provider can be injected using the standard IoC container.

The guys who wrote Professional ASP.NET MVC 3 also created fluent implementations of those, so you can have configuration like this:

validationProvider.ForModel<PersonModel>()
 .ForProperty(p => p.Name).Required()
 .ForProperty(p => p.Email).Required().Email();

This will also be picked up by the unobtrusive validation jQuery plugin, and everything else in MVC that would've used the attributes for.

As a sidenote, since you also derive from DynamicObject in your base class, the compiler won't complain if someone inadvertedly attempts to set person.name instead of person.Name.

answered Jan 26, 2012 at 9:44
\$\endgroup\$
1
  • \$\begingroup\$ Looking at this again I agree with your thoughts 'having to derive from a base class is just as bad as having to add attributes' Thanks Lars-Erik \$\endgroup\$ Commented Jan 26, 2012 at 15:35

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.