0

I am building a to-do-list project as a practice. It has one relationship to the Member model and the Member model has many relationships to 'to-do-list'

Member controller create method works without any issue but the to-do-list controller throws model state is invalid on Member object property of to-do-list

ToDoList

using System.ComponentModel.DataAnnotations;

namespace To_Do_List.Models
{
    public class ToDoList
    {
        [Key]
        public int Id { get; set; }

        [Required]
        [StringLength(200, MinimumLength = 1, ErrorMessage = "To Do List Item cannot be longer than 200 characters.")]
        public string Title { get; set; }
        public string Description { get; set; }

        [DataType(DataType.Date)]
        public DateTime DueDate { get; set; }


        public string Priority { get; set; }
       
        public int AssignToId { get; set; }

        
        public Member AssignTo { get; set; }
        [Required]
        [StringLength(15, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.")]
        [RegularExpression("^(Completed|Not Completed)$", ErrorMessage = "The status must be Completed or Not Completed")]
        public string Status { get; set; }
        
    }
}

Member

using Microsoft.Build.Framework;

namespace To_Do_List.Models
{
    public class Member
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }

        [Required]
        public ICollection<ToDoList> ToDoLists { get; set; }
        
        
    }
}

create method of to do list controller

  public async Task<IActionResult> Create([Bind("Id,Title,Description,DueDate,Priority,AssignToId,AssignTo, Status")] ToDoList toDoList)
  {
            


            if (ModelState.IsValid)
            {
                _context.Add(toDoList);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }

            ViewData["AssignToId"] = new SelectList(_context.Members, "Id", "Id", toDoList.AssignToId);
            return View(toDoList);
  }

View method of to do list

public IActionResult Create()
        {
            return View();
        }

Create.cshtml

@model To_Do_List.Models.ToDoList

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

<h1>Create</h1>

<h4>ToDoList</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="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Description" class="control-label"></label>
                <input asp-for="Description" class="form-control" />
                <span asp-validation-for="Description" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="DueDate" class="control-label"></label>
                <input asp-for="DueDate" class="form-control" />
                <span asp-validation-for="DueDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Priority" class="control-label"></label>
                <input asp-for="Priority" class="form-control" />
                <span asp-validation-for="Priority" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Status" class="control-label"></label>
                <input asp-for="Status" class="form-control" />
                <span asp-validation-for="Status" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
5
  • How are you sending request from your view could you please attach that part? View is crucial to check. Commented Jan 25, 2023 at 1:09
  • @MdFaridUddinKiron I didn't send any request from view. public IActionResult Create() { return View(); } Commented Jan 25, 2023 at 1:28
  • Than, hows the request sending? If I understand correctly, you would like to bind Member along with list of ToDoList together right? If so your binding is not correct as well. However, its important to see, how the request are sending. Commented Jan 25, 2023 at 1:31
  • @MdFaridUddinKiron, Yes, I would like to bind the Member along with list of ToDoList. I added my view method and create.cshtml I haven't sent anything from the view method. Do I need to send anything from the view method? Commented Jan 25, 2023 at 1:37
  • Wait a while, I am investigating your scenario. Commented Jan 25, 2023 at 2:00

1 Answer 1

1

Member controller create method works without any issue but the to-do-list controller throws model state is invalid on Member object property of to-do-list

Well, I have succssfully reproducced your issue and your ModelState.IsValid false is logical. Because, when you leave public Member AssignTo { get; set; } with default annotation it means required. whilist, you haven't pass any property from your view consequently, your bindings always be false as you have defined it into the [Bind] property that is AssignTo However, value has not been pass to it.

How to resolve:

In this scenario, you either has to pass AssignTo to your create action or make it nullable using ? annotation as following:

 public Member? AssignTo { get; set; }

Note: If you don't want to set AssignTo as nullable then you have to pass all property value from your view as following:

            <div class="form-group">
                <label asp-for="AssignTo.Name" class="control-label"></label>
                <input asp-for="AssignTo.Name" class="form-control" />
                <span asp-validation-for="AssignTo.Name" class="text-danger"></span>
            </div>

Here, I am passing only AssignTo.Name you have to pass rest of the values.

Output:

enter image description here

Note: If you would like to know more details on it you could check our official document here.

Sign up to request clarification or add additional context in comments.

2 Comments

No wait, I found another issue, I am updating the answer within a while.
Now you can have try and it would resolve your issue

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.