2

As I'm using database first I validate my inputs via ViewModel. But is that good enough for validation or is there some unwritten rule to add it e.g. in controller?

Also, what are the most common for attribute-validation, lets say password?

[Required]
[StringLength(50)]
[MinLength(3)]
public string Password { get; set; }

Is this a good validation?

Nyprez
  • 306
  • 4
  • 18
  • I'll be happy to stand corrected, but I *believe* those attributes will set the HTML dynamically, so that input will have the `required` attribute set, for example. But I can't recall it ever doing server-side checks for you. You'd likely have to sanitize the data in your controller as well, which is never a bad practice. – Drew Kennedy Sep 30 '16 at 18:16
  • @DrewKennedy Aah I see. Do you know any good guide about adding validation inside controller? – Nyprez Sep 30 '16 at 18:20
  • Not so much a guide, but you can always use `ModelState` to run a validation check, and `AddModelError` to define each problem, or use the property to define the error message. [Here's a good example](http://stackoverflow.com/a/21911236/4204026). – Drew Kennedy Sep 30 '16 at 18:23
  • The data annotations will also enforce server-side checks. The `ModelState.IsValid` will be updated based on the validation success/failure. As far as password validation goes, I guess it depends on how you want your passwords to look. MinLength 3? I mean a 3 character password sounds pretty bad to me. I'd think more like 8, maybe 10. Maybe enforce some rules like including numbers letters symbols, etc. – dmeglio Sep 30 '16 at 18:23
  • 1
    I would say `MinLength(3)` is pretty weak for a password. – stephen.vakil Sep 30 '16 at 18:25
  • @dman2306 I see, thanks. – Nyprez Sep 30 '16 at 18:32
  • Sometimes you'll want separate client-side and server-side rules on the same post. But in any case, you should _always validate server-side_ because malicious users can and will by-pass any client-side checks you put into place. – Jasen Sep 30 '16 at 18:42
  • @Jasen I'll also add, not just malicious users, sometimes "regular" users too. For example if you do client side HTML5 validation and I'm on an older browser, I, as the user, may never even know I'm violating your validation rules! – dmeglio Sep 30 '16 at 19:01
  • @Jasen Oh good to know! Do I validate server-side by `ModelState` in controller? New to MVC, not really sure about client/server side yet. – Nyprez Sep 30 '16 at 19:40
  • Yes, do your checks in the controller. – Jasen Sep 30 '16 at 23:06

2 Answers2

2

The attribute validation is perfectly good for what it can do. In addition to the validation attributes you mention, you have the EmailAddress attribute which validates the given property as an e-mail address.

[EmailAddress(ErrorMessage = "Invalid Email Address")]

Then you have the RegularExpression validation attribute for doing more complicated custom validations:

[RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$", 
         ErrorMessage = "Characters are not allowed.")]

For conditional validation and such things, you can add that logic to your controller and add errors to the ModelState as needed.

Example:

if (MyProperty == "something" && MyOtherProperty != "something")
{
    ModelState.AddModelError("", "MyOtherProperty needs to be something")
}

If you don't want such boilerplate validation code in your controller logic, you can write your own custom validation attributes. By doing so, you can pretty much validate whatever you can think of.

There's plenty of resources about that topic on the Internet.

How to create a custom validation attribute?

How to create Custom Data Annotation Validators

To name a few.

Community
  • 1
  • 1
HaukurHaf
  • 13,522
  • 5
  • 44
  • 59
0

Don't forget to check the validity of the ModelState by calling ModelState.IsValid. Besides this, I can imagine you need to do some additional database validation checks.

user1796440
  • 366
  • 3
  • 11
  • by additional database validation checks, what do you mean for example? – Nyprez Sep 30 '16 at 18:30
  • Let's say someone registers an account. The values entered by him could be valid, but you would still want to check in the database if the entered user name is not already taken. – user1796440 Sep 30 '16 at 18:35
  • Aah I see! Am I suppose to do that trough controller? Lets say a `Username`. If `Username` already exist in database(still trough controller) I will return "already exist"- error. If not, the `Username` will be added. Is that a correct way to do it? – Nyprez Sep 30 '16 at 19:44