I have a model with some validation rules like minimum string length of 12.
public class Client{
[Required("ID Cannot be empty")]
[StringLength(12, ErrorMessage="ID must have 12 characters", MinimumLength = 12)]
public string Id { get; set; }
[Required("Name cannot be empty")]
[StringLength(60, ErrorMessage="Must be between 10 and 60 characters", MinimumLength = 10)]
public string FullName { get; set; }
[Required("Phone cannot be empty")]
[StringLength(9, ErrorMessage="Phone number must have 9 characters", MinimumLength = 9)]
public string PhoneNumber { get; set; }
[Required("Client needs a status")]
public bool PremiumStatus { get; set; }
}
These rules work in a Registration
view I have, meaning I get to see the validation messages and the model isn't registered if it's not valid.
However, in my Search/Edit view, where I should be able to look for an Id and modify the returned model, none of the changes are registering, and upon debugging the app, I see that the ModelState
for the model is always invalid, however, at the same time, I do not see any validation message
@model MyApp.Models.Client
@{
ViewBag.Title = "MyApp"
}
@using(Html.BeginForm("Search", "Search", FormMethod.Post)){
Search for ID: @Html.TextBox("SearchId")
<input type="submit" value="Search"/>
}
@using(Html.BeginForm("EditClient", "Search", FormMethod.Post)){
@Html.LabelFor(m => m.Id)
@Html.DisplayFor(m => m.Id)
@Html.LabelFor(m => m.FullName)
@Html.EditorFor(m => m.FullName)
@Html.ValidationMessageFor(m => m.FullName)
@Html.LabelFor(m => m.PhoneNumber)
@Html.EditorFor(m => m.PhoneNumber)
@Html.ValidationMessageFor(m => m.PhoneNumber)
@Html.LabelFor(m => m.PremiumStatus)
@Html.EditorFor(m => m.PremiumStatus)
@Html.ValidationMessageFor(m => m.PremiumStatus)
<input type="submit" value="Save Changes"/>
}
Note that I only want to edit the Name, phone and status. I do not want to edit the ID, hence it's only a display field
Now on my controller
public class SearchController : Controller {
public ActionResult Search() {
return View();
}
[HttpPost]
public ActionResult Search(string SearchId) {
//Searching my Session variable to retrieve Client item related to the code searched.
//I have validations in place in case the ID doesn't exist, but I'm not showing them to keep the code simple.
Client clientFound = (Client) Session[SearchId];
//Returns the view with the found model, populating all of the fields in the view.
return View("Search", clientFound)
}
[HttpPost]
//I just added these 2 annotations, but it wasn't working without them either
[ValidateAntiForgeryToken]
[ValidateInput(true)]
public ActionResult EditClient(Client model) {
if(ModelState.IsValid){
Session[model.Id] = model;
Debug.WriteLine("Client updated");
}
return RedirectToAction("Search");
}
}
By setting up breakpoints, I could see that once inside EditClient
, the model does have the correct, newly updated properties assigned to it. It's just that it's always considered invalid. And as mentioned before, even if I delete everything from the editable fields, I don't get an error message showing they're invalid.