如何克服 Asp.net 导航的 MVC 验证错误 属性

How to overcome Asp.net MVC validation error for navigation property

场景:

我正在使用 Entity Framework 实施 Asp.Net MVC 项目。我有以下实体:

class Employee{
   public int Id{get;set;}
   [Required]
   public string Name{get;set;}
}

class Department{
   public int Id{get;set;}
   public string DepartmentName{get; set;}
   public virtual Employee manager{get; set;}
}

现在,我必须创建一个新部门,该部门的经理来自数据库中的员工列表。为此,视图和控制器操作是:

@Html.EditorFor(model => model.DepartmentName)
@Html.DropDownListFor(model => model.manager.Id, new SelectList(ViewBag.Managers, "Id", "Name"))


public class DepartmentController: Controller{
    private MyDatabaseContext db = new MyDatabaseContext();

    [HttpGet]
    public ActionResult Create(){
        ViewBag.Managers = db.Employees.ToList();
        return View();
    }

    [HttpPost]
    public ActionResult Create(Department d){
       if(ModelState.IsValid){
          d.manager = db.Employees.Find(d.manager.Id);
          db.Departments.Add(d);
          db.SaveChanges();
          return RedirectToAction("Index");
       }
       else{
         //error response.
         //Error encounters as d.manager.Name field would be null.
       }
    }
}

问题:

当 运行 以上程序时,我无法创建新的 Department 对象,因为 ModelState.IsValid 始终是 false。原因是导航 属性 manager 有字段 Name,在提交表单时会是 null。由于 Name 是必填字段,这将被列为错误。

问题:

如何克服由于 null 在导航领域 属性 引起的错误?或者,是否有其他方法来实现此代码,以便我摆脱此错误?

备注:

请注意,我不想创建仅对创建 Department 对象有用的不同 ViewModel。我宁愿遵循 DRY 原则。 此外,我不想创建不同的字段(类似于 managerId),这将是 Employees table 的外键,因为我不希望数据库关联在面向对象模型。通过 department.manager 检索管理器总是比通过传递 department.managerId [Key] 字段从 entity framework 读取管理器对象更清晰。

谢谢。

你需要这个

public int EmployeeId {get;set;} 

在部门。

Please make note that I don't want to create different ViewModel merely useful for creating the Department object. I would prefer following DRY principle.

在这种情况下使用视图模型并不违反DRY原则。视图模型代表不同的概念(即您的视图需要的数据)。这与数据库 table(域模型)所需的数据完全不同。如果你的view model和domain model刚好在你最初实现的时候有相同的属性,那就是纯属巧合.

DRY 原则是关于确保您不会在多个地方重复相同的概念

使用视图模型绝对是正确的方法,特别是在您的情况下,因为它允许数据访问层的验证要求独立于 UI 层的验证要求而变化。通过在 UI 中重复使用域模型,您将失去执行此操作的灵活性,并且您将不断 运行 陷入您正在描述的同一问题。