Cohiba
Cohiba

Reputation: 23

ASP.NET MVC - ModelState is invalid but form content is acessible

I am trying to pass some input from the "Create" view to my controller but the ModelState is returning error:

The Controller:

[Route("Create")]
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create([Bind("Name, Location, MaxCapacity")] Warehouse warehouse)
{

    if (ModelState.IsValid)
    {
        _Db.Add(warehouse);
        _Db.SaveChanges();
        return RedirectToAction("Index");
    }

    return BadRequest();
}

The view:

@model InventoryManSys.Models.Warehouse

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Warehouse</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Name" class="control-label"></label>
                <input asp-for="Name" class="form-control" />
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Location" class="control-label"></label>
                <input asp-for="Location" class="form-control" />
                <span asp-validation-for="Location" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="MaxCapacity" class="control-label"></label>
                <input asp-for="MaxCapacity" class="form-control" />
                <span asp-validation-for="MaxCapacity" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

The model:

public class Warehouse
{
    [Key]
    public int Id { get; set; }
    [Required]
    [StringLength(30, ErrorMessage = "Name should have less than 30 characters")]
    [DisplayName("Warehouse Name")]
    public string Name { get; set; }
    [Required]
    public string Location { get; set; }
    [Required]
    public int MaxCapacity { get; set; }

    //Navigation Property
    public ICollection<Category> Categories { get; set; }

}

But when I do a "Console.WriteLine(warehouse.Name)" the input is being passed correctly. How to solve that? is the "bind[]"attribute a problem?

Upvotes: 0

Views: 1683

Answers (1)

Rena
Rena

Reputation: 36565

ModelState is invalid but form content is acessible

You may add the client validation js library jquery.validate.js and jquery.validate.unobtrusive.js.

Check this document:

https://learn.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-6.0#client-side-validation

If Name/Location/MaxCapacity are received value, it should work fine, suggest you can check the ModelState or just return BadRequest(ModelState); to see what's the detailed error.

But if you use .NET 6, as this document said:

Beginning with .NET 6, new projects include the <Nullable>enable</Nullable> element in the project file. Once the feature is turned on, existing reference variable declarations become non-nullable reference types.

So that the non-nullable property must be required in ASP.NET 6, otherwise the ModelState will be invalid.

One way is to remove <Nullable>enable</Nullable> from your project file.

Another way is to add ? like below:

public class Warehouse
{
    [Key]
    public int? Id { get; set; }
    [Required]
    [StringLength(30, ErrorMessage = "Name should have less than 30 characters")]
    [DisplayName("Warehouse Name")]
    public string Name { get; set; }
    [Required]
    public string Location { get; set; }
    [Required]
    public int MaxCapacity { get; set; }

    //Navigation Property
    public ICollection<Category>? Categories { get; set; }

}

Upvotes: 2

Related Questions