使用继承 asp.net 核心 3.1 时表单验证不起作用

Form Validation not working when using inheritance asp.net core 3.1

我是 asp.net 核心的初学者,刚刚开始一个 EmployeeManagement 项目,其中 Employee 是我的基础 class:

public class Employee
{
    public int Id { get; set; }

    [Required]
    [Display(Name="First Name")]
    public string Name { get; set; }

    [Required]
    [Display(Name="Official Email ID")]
    [RegularExpression(@"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$",
    ErrorMessage = "Invalid email format")]
    public string Email { get; set; }
    
    public string Department { get; set; } 
}

DropdownListModel 是我的第二个 class,它继承自基础 class 员工:

public class DropdownListModel:Employee
{ 
    public SelectList Departmentcollection { get; set; }
}

Departmentcollection 用于在我创建新员工时将项目填充到数据库的下拉列表中。

     <form asp-controller="home" asp-action="CreateEmp" method="post">
        <div class="form-group">

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

        <div>
            <label asp-for="Email"></label>
            <input asp-for="Email" class="form-control">
            <span asp-validation-for="Email" class="text-danger"></span>
        </div>

        <div>
            <label asp-for="Department"></label>
            
            <select asp-for="Department"
        asp-items=@Model.Departmentcollection class="form-control"></select>

        </div>
    <div>
    <button type="submit" class="btn btn-dark" >Create</button>
    </div>
     [HttpPost]
    public IActionResult CreateEmp(Employee emp)
    {
        if(!ModelState.IsValid)
        {
            return View();

        }

       Employee NewEmployee= repository.AddEmployee(emp);
        return RedirectToAction("Details",new { Id = NewEmployee.Id });
        
    }
 [HttpGet]
public ViewResult CreateEmp()
    {
       return View (new DropdownListModel { Departmentcollection 
      = new SelectList(
     repository
       .employees.Select(d => d.Department).Distinct()) 
       });
        

       
    }

代码工作正常,下拉列表正在填充,记录正在插入。

问题是验证不工作。

我得到的错误是:

An unhandled exception occurred while processing the request.
NullReferenceException: Object reference not set to an instance of an object.
AspNetCore.Views_Home_CreateEmp.<ExecuteAsync>b__19_0() in 
CreateEmp.cshtml
asp-items=@Model.Departmentcollection class="form-control"></select> 
Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.GetChildContentAsync(bool useCachedResult, HtmlEncoder encoder)

我做错了什么?

我使用了虚拟和覆盖属性仍然是同样的错误。

services.AddControllersWithViews(options => options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true); 

An unhandled exception occurred while processing the request. NullReferenceException: Object reference not set to an instance of an object.

NullReferenceException 是由 空对象值 引起的。在您的场景中,它是由详细错误消息中的 asp-items=@Model.Departmentcollection 引起的。

假设您的后端代码如下所示:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> CreateEmp(DropdownListModel obj)
{         
    //do your stuff to add to database.....         
    return View(obj);
}

您可以看到您的错误消息是在 CreateEmp.cshtml 中引起的,并且您说下拉列表是第一次填充。也就是说,您的代码必须步进代码 return View(obj),在这种情况下它会 post 返回以再次呈现 CreateEmp.cshtml 并且可能会导致一些问题。您可以调试您的代码来检查您收到的模型,并发现 Departmentcollection 没有值。因为 <select asp-for="Department"> 将在表单提交时将所选值发送到 Department 属性。

最重要的是,您需要在 return 如下视图之前再次重置下拉列表值:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> CreateEmp(DropdownListModel obj)
{         
    if(!ModelState.IsValid)
    {
        var data = new DropdownListModel()
        {
            Id = obj.Id,
            Department = obj.Department,
            Email = obj.Email,
            Name = obj.Name,
            Departmentcollection = new SelectList(repository.employees.Select(d => d.Department).Distinct())
        };
        return View(data);
    }
    Employee NewEmployee= repository.AddEmployee(emp);
    return RedirectToAction("Details",new { Id = NewEmployee.Id });
}