0

I have searched for hours for the problem I am facing and can't find anything that helps my problem. I am practicing ASP.NET Core MVC and trying to post a model, but its values keep becoming null on HTTP Post. Here are my models:

public class Employee
{
    [Key]
    public int Id { get; set; }

    [Required]
    public string FirstName { get; set; }

    [Required]
    public string LastName { get; set; }

    [Required]
    [Range(16,82)]
    public int Age { get; set; }

    [Required]
    [Range(0,350000)]
    public decimal Salary { get; set; }

    public int DepartmentId { get; set; }

    public Department Department { get; set; }

    public string GetFullName => $"{FirstName} {LastName}";
}


public class Department
{
    [Key]
    [Required]
    public int Id { get; set; }

    [Required]
    public string DepartmentName { get; set; }

    public string Description { get; set; } = "N/A";

    public List<Employee> Employees { get; set; } = new List<Employee>();
}

Here is the form in question:

  @model Employee
     
@{
}

<form method="post">
    <div>
        <label asp-for="FirstName" class="form-label"></label>
        <input asp-for="FirstName" class="form-control"/>
    </div>

    <div>
        <label asp-for="LastName" class="form-label"></label>
        <input asp-for="LastName" class="form-control" />
    </div>

    <div>
        <label asp-for="Age" class="form-label"></label>
        <input asp-for="Age" class="form-control" />
    </div>

    <div>
        <label asp-for="Department.DepartmentName" class="form-label">Department</label>
        <input asp-for="Department.DepartmentName" disabled class="form-control" />
    </div>

    <div>
        <label asp-for="Salary" class="form-label"></label>
        <input asp-for="Salary" class="form-control" />
    </div>

    <br />
    <button type="submit" class="btn btn-primary">Add employee</button>
    <a asp-action="ListDepartments">Cancel</a>
</form>

and here is the controller in question:

    public class DepartmentController : Controller
    {
        private DepartmentEmployeeDatabaseContext dbContext { get; set; }

        public DepartmentController(DepartmentEmployeeDatabaseContext ctx)
        {
            dbContext = ctx;
        }

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

        public IActionResult ListDepartments()
        {
            IEnumerable<Department> departments = dbContext.Departments;
            return View(departments);
        }

        public IActionResult AddEmployee(int? id)
        {
            Department department = new Department();
            Employee employee = new Employee();

            try
            {
                department = dbContext.Departments.Find(id);
                employee.Department = department;
                employee.DepartmentId = department.Id;
            }
            catch (Exception e)
            {
                return View();
            }

            return View(employee);
        }

        [HttpPost]
        [AutoValidateAntiforgeryToken]
        public IActionResult AddEmployee(Employee emp)
        {
            if (ModelState.IsValid)
            {
                dbContext.Add(emp);
                dbContext.SaveChanges();
                return RedirectToAction("ListDepartments");
            }

            return View(emp);
        }
    }

The IActionResult AddEmployee(int? id) method works fine (assigns a department and department id to a new employee object) but the values become null inside the public IActionResult AddEmployee(Employee emp) method. What exactly am I doing wrong? Thanks in advance!

2 Answers 2

0

You can get results if you change it to

     @model Employee
     
<form method="post">
     <div>
            <label asp-for="@Model.FirstName" class="form-label"></label>
            <input asp-for="@Model.FirstName" class="form-control"/>
        </div>
 <div>
        <label asp-for="@Model.LastName" class="form-label"></label>
        <input asp-for="@Model.LastName" class="form-control" />
    </div>

    <div>
        <label asp-for="@Model.Age" class="form-label"></label>
        <input asp-for="@Model.Age" class="form-control" />
    </div>
        <div>
        <label asp-for="@Model.Department.DepartmentName" class="form-label">Department</label>
        <input asp-for="@Model.Department.DepartmentName" disabled class="form-control" />
    </div>

    <div>
        <label asp-for="@Model.Salary" class="form-label"></label>
        <input asp-for="@Model.Salary" class="form-control" />
    </div>

         <button type="submit" asp-controller="Department" asp-action="AddEmployee" class="btn btn-primary">Add employee</button>
<form>
Sign up to request clarification or add additional context in comments.

3 Comments

thanks for taking the time to reply. I tried your method and I'm still losing the department values on post (department becomes null and the departmentId becomes 0).
Maybe it will help if you create certain departments and assign them via the view, for example, you can specify 4 departments and present them to the user with the option. I can't help more as I haven't seen the whole code.
This is because your department value has attribute disabled in the input. Disabled inputs dont get posted back to server. Instead you can use readonly attribute for that.
0

First, disabled attribute will not submit this <input> tag, So you can try to use readonly attribute. Tag help asp-for need property's name as the key, You can change your code like this:

<div>
        <label asp-for="Department.DepartmentName" class="form-label">Department</label>
        <input asp-for="Department.DepartmentName" readonly class="form-control" />            
        <input asp-for="Department.Id" type="hidden" />            
        <input asp-for="Department.Description" type="hidden" />
        <input asp-for=DepartmentId type="hidden" />
    </div>

Then you can get the value of Department and DepartmentId:

enter image description here

Comments

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.