Reputation: 63
As is typical in MVC, I have a View, a Model, and a Controller.
The View contains a form:
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.HiddenFor(m => m.Id)
<ul class="fieldlist">
<li>
@Html.LabelFor(m =>m.Email)
@Html.TextBoxFor(m => m.Email)
@Html.ValidationMessageFor(m => m.Email)
</li>
<li>
<div class="row">
<div class="col-md-6">
@Html.LabelFor(m => m.FirstName)
@Html.TextBoxFor(m => m.FirstName)
@Html.ValidationMessageFor(m => m.FirstName)
</div>
<div class="col-md-6">
@Html.LabelFor(m => m.LastName)
@Html.TextBoxFor(m => m.LastName)
@Html.ValidationMessageFor(m => m.LastName)
</div>
</div>
</li>
<li>
@Html.LabelFor(m => m.PhoneNumber)
@Html.TextBoxFor(m => m.PhoneNumber)
@Html.ValidationMessageFor(m => m.PhoneNumber)
</li>
<li>
<div Class="row">
<div Class="col-md-2">
<input type="submit" value="Save" />
</div>
</div>
</li>
</ul>
}
The model looks like this:
public class UserAdminUserViewModel
{
[Display(Name = "User Database ID"), DataType(DataType.Text)]
public string Id { get; set; }
[Display(Name = "Full Name")]
public string Name { get { return FirstName + " " + LastName; } }
[Required()]
[Display(Name = "First Name"), DataType(DataType.Text)]
public string FirstName { get; set; }
[Required()]
[Display(Name = "Last Name"), DataType(DataType.Text)]
public string LastName { get; set; }
[Required()]
[Display(Name = "Email Address"), DataType(DataType.EmailAddress)]
public string Email { get; set; }
[Display(Name = "Telephone Number"), DataType(DataType.Text)]
public string PhoneNumber { get; set; }
}
And the controller to receive the updates:
[HttpPost,ValidateAntiForgeryToken]
public ActionResult User(UserAdminUserViewModel model)
{
if (ModelState.IsValid)
{
// do something, apply the updates to the database, presumably
}
return View(model);
}
...but ModelState.IsValid is always true. The controller is receiving the entered information, but it appears that no validation is taking place. I have tried:
TryUpdateModel<UserAdminUserViewModel>(model);
and
UpdateModel<UserAdminUserViewModel>(model);
I'm not sure I see how these would work, but they were the first suggestions I came across. No dice. Still valid regardless of the data in 'model'. I also tried:
System.ComponentModel.DataAnnotations.Validator.ValidateObject(model, new System.ComponentModel.DataAnnotations.ValidationContext(model));
More promising, but still doesn't work. I also tried the more verbose approach:
System.ComponentModel.DataAnnotations.ValidationContext valContext = new System.ComponentModel.DataAnnotations.ValidationContext(model, null, null);
List<System.ComponentModel.DataAnnotations.ValidationResult> valResults = new List<System.ComponentModel.DataAnnotations.ValidationResult>();
System.ComponentModel.DataAnnotations.Validator.TryValidateObject(model, valContext, valResults, true);
foreach(System.ComponentModel.DataAnnotations.ValidationResult result in valResults)
{
this.ModelState.AddModelError(result.MemberNames.FirstOrDefault() ?? string.Empty, result.ErrorMessage);
}
...which also didn't work. 'valResults', which should contain any errors in the state of the model, is never filled; no validation is happening.
Upvotes: 1
Views: 1903
Reputation: 12611
I would use this for email validation:
@using using System.ComponentModel.DataAnnotations;
[Required]
[EmailAddress]
[Display(Name = "Email Address")]
public string Email { get; set; }
Please see this StackOverflow post
However, EmailAddressAttribute adds server-side validation on top of that. I.e. there is no server-side validation if you only use DataTypeAttribute!
Upvotes: 2
Reputation: 5703
If the problem with incorrect email address, here's the solution:
[Email(ErrorMessage = "Invalid Email Address")]
[Required()]
[Display(Name = "Email Address"), DataType(DataType.EmailAddress)]
public string Email { get; set; }
DataType(DataType.EmailAddress)
means only how to show textbox on client-side, while Email
attribute does actual validation.
Upvotes: 0