Dasph
Dasph

Reputation: 446

ASP.NET MVC5 ModelState is always invalid while simultaneously not showing validations

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.

Upvotes: 0

Views: 590

Answers (2)

tontonsevilla
tontonsevilla

Reputation: 2809

On your Client model the property Id is required.

Since it is required you need to make sure that you have an input field corresponding to your Id property which I couldn't find any input field that correspond to it on your .cshtml.

You can include a @Html.HiddenFor(m => m.Id) (which is an input field with a type hidden) so that when you submit the form Id will still be included in the post.

Upvotes: 1

Abiola Akinnubi
Abiola Akinnubi

Reputation: 313

I think you should read more about ModelState in ASP.NET.

here are some StackOverflow answers that may be helpful along with microsoft official documentation.

  1. What does ModelState.IsValid do?
  2. https://learn.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api
  3. https://www.exceptionnotfound.net/asp-net-mvc-demystified-modelstate/

Now to put a bit of light on your question. One of your fields that are set as required is not having the data type or content that your action is expecting for this field has not been set with the appropriate data type. I would natural suggest that for edit and search feature you should use other forms of validation rather than ModelState. So for an hypothetical solution your edit view should naturally have like a modal view where is if I select a detailed it shows me the current data that this user information has by fetching by the user id. then I can submit my edit along with the content and the user Id, this will then update the database with the new data where there is a match by the ID with the assumption that the ID is unique for each user.

Thanks Please read the links shared.

Upvotes: 0

Related Questions