Search code examples
razorasp.net-core-mvc.net-6.0

How to populate CreateGroupViewModel


I'm having trouble with inputting value into a ViewModel as it keep returning null after the value is inputted via cshtml.

Value I input in cshtml enter image description here

After hitting confirm enter image description here

CreateViewModel.cs

public class CreateGroupViewModel
{
    public string AppUserId { get; set; }
    public AppUser AppUser { get; set; }
    public Department Department { get; set; }
    public DayGroup DayGroup { get; set; }
}

DayGroup.cs

public class DayGroup
{
    public string Id { get; set; }
    public DateTime SubcriptionDate { get; set; }
    public Group Group { get; set; }
}

Create Method

[HttpGet]
public async Task<IActionResult> Create() 
{
    var userId = _contextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
    var appUser = await _appUserRepository.GetByIdAsync(userId);
    var department = await _groupRepository.GetDepartmentByUserAsync(appUser);
    var createGroupViewModel = new CreateGroupViewModel()
    {
        AppUserId = userId,
        AppUser = appUser,
        Department = department,
    };
    createGroupViewModel.Department.Persons = await _groupRepository.GetPeopleByDepartmentAsync(department);
    return View(createGroupViewModel);
}

[HttpPost]
public async Task<IActionResult> Create(CreateGroupViewModel model)
{
    model.AppUserId = _contextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
    model.AppUser = await _appUserRepository.GetByIdAsync(model.AppUserId);
    model.Department = await _groupRepository.GetDepartmentByUserAsync(model.AppUser);
    //all other logic
}

Create.cshtml

@using QLAnCaWeb.ViewModels
@model CreateGroupViewModel
<div class="container mb-3">
    <div class="row pt-4">
        <div class="col-6">
            <h2 class="text-primaary">
                ĐĂNG KÝ ĂN CA CHO TẬP THỂ
            </h2>
            <h3>
                HỌ TÊN: @Model.AppUser.Name
            </h3>
            <h3>
                PHÒNG BAN: @Model.Department.DepartmentName
            </h3>
            <form method="post" asp-action="Create">
                @{
                    Model.DayGroup = new DayGroup();
                }
                <div class="row g-3 align-items-center">
                    <div class="col-auto">
                        <label  for="SubDate" class="col-form-label">NGÀY ĐĂNG KÝ: </label>
                    </div>
                    <div class="col-auto">
                        <input type="date" id="SubDate" asp-for="@Model.DayGroup.SubcriptionDate" class="form-control" />
                        <span asp-validation-for="@Model.DayGroup.SubcriptionDate" class="text-dark"></span>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>
<form method="post" asp-action="Create" class="row g-3">
    <div class="mb-3 row">
        <div class="col-sm-3">
            <input type="text" readonly class="form-control-plaintext" value="DS HỌ TÊN" />
        </div>
        <div class="col">
            <input type="text" readonly class="form-control-plaintext" value="CA 1" />
        </div>
        <div class="col">
            <input type="text" readonly class="form-control-plaintext" value="CA 2" />
        </div>
        <div class="col">
            <input type="text" readonly class="form-control-plaintext" value="CA 3" />
        </div>
    </div>
    @foreach (var person in Model.Department.Persons)
    {
        <div class="row">
            <div class="col">
                <input type="text" readonly class="form-control-plaintext" value="@person.Name">
            </div>
            <div class="col">
                <input class="form-control" type="number" asp-for="@person.Set1" />
                <span asp-validation-for="@person.Set1" class="text-dark"></span>
            </div>
            <div class="col">
                <input class="form-control" type="number" asp-for="@person.Set2" />
                <span asp-validation-for="@person.Set2" class="text-dark"></span>
            </div>
            <div class="col">
                <input class="form-control" type="number" asp-for="@person.Set3" />
                <span asp-validation-for="@person.Set3" class="text-dark"></span>
            </div>
        </div>
    }
    <div class="row g-3 align-items-center">
        <div class="col-auto">
            <button type="submit" class="btn btn-primary">Submit</button>
        </div>
        <div class="col-auto">
            <a class="btn btn-danger" asp-controller="Home" asp-action="Index">Cancel</a>
        </div>
    </div>
</form>

I want it to populate CreateViewModel with DayGroup and Department alongside DayGroup and Department appropriate values


Solution

  • There are two form tags in your view, which will cause the submit button to not recognize all the attributes in the two forms. Secondly, when you process the Model.Department.Persons collection, you use foreach, which may cause the server to not correctly bind the form data to the corresponding attributes of the model. enter image description here

    You can change the attempt to use the for loop to use this index to access each element in the collection to ensure that the server can recognize the corresponding attributes of the model when the form is submitted. Here is an example for your reference, in which I provide the view code, which configures a list type person in the Department model, and the person model has Name, set1, set2, set3 attributes:

    public class CreateGroupViewModel
    
        {
            public string AppUserId { get; set; }
            public AppUser AppUser { get; set; }
            public Department Department { get; set; }
            public DayGroup DayGroup { get; set; }
        }
        public class DayGroup
        {
            public string Id { get; set; }
            public DateTime SubcriptionDate { get; set; }
            public Group Group { get; set; }
        }
    
        public class AppUser
        {
            public string Id { get; set; }
           public string  Name { get; set; }
        }
    
        public class Department
        {
            public string Id { get; set; }
            public string DepartmentName { get; set; }
    
            public List<Person> Persons { get; set; }
        }
    
        public class Person
        {
            public string Name { get; set; }
            public int Set1 { get; set; }
            public int Set2 { get; set; }
            public int Set3 { get; set; }
        }
    }
    

    View:

    @model CreateGroupViewModel
    
    <div class="container mb-3">
        <div class="row pt-4">
            <div class="col-6">
                <h2 class="text-primary">
                    ĐĂNG KÝ ĂN CA CHO TẬP THỂ
                </h2>
                <h3>
                    HỌ TÊN: @Model.AppUser.Name
                </h3>
                <h3>
                    PHÒNG BAN: @Model.Department.DepartmentName
                </h3>
                <form method="post" asp-action="Create">
                    <div class="row g-3 align-items-center">
                        <div class="col-auto">
                            <label for="SubDate" class="col-form-label">NGÀY ĐĂNG KÝ: </label>
                        </div>
                        <div class="col-auto">
                            <input type="date" id="SubDate" asp-for="DayGroup.SubcriptionDate" class="form-control" />
                            <span asp-validation-for="DayGroup.SubcriptionDate" class="text-dark"></span>
                        </div>
                    </div>
    
                    <div class="mb-3 row">
                        <div class="col-sm-3">
                            <input type="text" readonly class="form-control-plaintext" value="DS HỌ TÊN" />
                        </div>
                        <div class="col">
                            <input type="text" readonly class="form-control-plaintext" value="CA 1" />
                        </div>
                        <div class="col">
                            <input type="text" readonly class="form-control-plaintext" value="CA 2" />
                        </div>
                        <div class="col">
                            <input type="text" readonly class="form-control-plaintext" value="CA 3" />
                        </div>
                    </div>
    
                    @for (int i = 0; i < Model.Department.Persons.Count; i++)
                    {
                        <div class="row">
                            <div class="col">
                                <input type="text" readonly class="form-control-plaintext" value="@Model.Department.Persons[i].Name">
                            </div>
                            <div class="col">
                                <input class="form-control" type="number" asp-for="Department.Persons[i].Set1" />
                                <span asp-validation-for="Department.Persons[i].Set1" class="text-dark"></span>
                            </div>
                            <div class="col">
                                <input class="form-control" type="number" asp-for="Department.Persons[i].Set2" />
                                <span asp-validation-for="Department.Persons[i].Set2" class="text-dark"></span>
                            </div>
                            <div class="col">
                                <input class="form-control" type="number" asp-for="Department.Persons[i].Set3" />
                                <span asp-validation-for="Department.Persons[i].Set3" class="text-dark"></span>
                            </div>
                        </div>
                    }
    
                    <div class="row g-3 align-items-center">
                        <div class="col-auto">
                            <button type="submit" class="btn btn-primary">Submit</button>
                        </div>
                        <div class="col-auto">
                            <a class="btn btn-danger" asp-controller="Home" asp-action="Index">Cancel</a>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
    

    enter image description here

    After I submit the relevant data:

    enter image description here

    enter image description here

    enter image description here