3

I've been googling like crazy without result, maybe I'm just missing the correct keywords.

I have a class with a custom validation attribute on a property. I want to "clean" the value before validation, removing the white-space and special characters that we accept but that we don't want to save to the database.

public class PersonViewModel
{
    [SocialSecurityNumberLuhn(ErrorMessage = "Incorrect social security number")]
    public string SocialSecurityNumber { get; set; }
}

I would want to do something like this:

public class PersonViewModel
{
    [CleanWhiteSpace]
    [SocialSecurityNumberLuhn(ErrorMessage = "Incorrect social security number")]
    public string SocialSecurityNumber { get; set; }
}

For example 1985-03-15-1234 should be saved and validated as 19850315-1234.

Any suggestions? What's the neatest approach?

1
  • Then you need a custom ModelBinder for this Commented Sep 29, 2014 at 14:45

2 Answers 2

3

If you change the auto-implemented property into a manual-implemented property then you can perform the "cleaning" step when the value is set, so it can only be stored in the model in a "clean" state. Something like this:

public class PersonViewModel
{
    private string _socialSecurityNumber;

    [SocialSecurityNumberLuhn(ErrorMessage = "Incorrect social security number")]
    public string SocialSecurityNumber
    {
        get { return _socialSecurityNumber; }
        set
        {
            _socialSecurityNumber = CleanSocialSecurityNumber(value);
        }
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

I did come over that kind of solution when I googled. Forgot to mention it in the question. Maybe that's the cleanest solution. Like it better than a custom model binder at least.
You've got two ways to handle this. Either you can make validation very strict and not accept the whitespace, or you can clean it at the model level and make the validation loose. The advantage of doing it at the model level is that you don't have to worry about both client and server-side, you only have to deal with server-side.
I have a static method that cleans the SSN in the setter. I do however need to clean the value in the ValdationAttribute as well for it to work. Less ideal solution, but still better than the custom model binder.
2

The recommended approach here is to use a service layer. View models should not include any logic. With a service layer Your controller would call a method on its associated service and this method would return your view model with the clean SSN.

In this tutorial you will see how the service layer can be structured and you could adapt the pattern to clean your data before validation.

http://www.asp.net/mvc/tutorials/older-versions/models-(data)/validating-with-a-service-layer-cs

The use of a ValidationAttribute in your example would be an incorrect usage also.

Controller where you would inject / instantiate the service class

public ActionResult GetPerson(int PersonId){ 
   return _personService.GetPerson(personId);
}

The service method

public PersonViewModel GetPerson(int Id){
  // get the data (maybe from DAL) and clean returning view model
  return new PersonViewModel(){SocialSecurityNumber = Clean(...)};
}

Hope this gives you some direction.

Comments

Your Answer

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.