当模型具有外键时,ModelState.IsValid 为 false

Posted

技术标签:

【中文标题】当模型具有外键时,ModelState.IsValid 为 false【英文标题】:ModelState.IsValid is false when model has a foreign key 【发布时间】:2021-09-14 07:52:46 【问题描述】:

我有一个MachineSettings 实体,这个实体有一个Machine 实体作为外键。

public class Machine

    [Key]
    public int MachineId  get; set; 

    [Required]
    [Display(Name = "Machine Type")]
    public string MachineName  get; set;         


public class MachineSettings
        
    [Key]
    public int MachineSettingId  get; set; 

    [Required]
    public string Password  get; set; 

    [Required]
    public int ReferenceKeyLength  get; set; 

    [Required]
    public virtual Machine MachineId  get; set; 

在我的控制器类中,当我将Edit 方法创建为POST 时:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(MachineSettings machineSettings)

        if (ModelState.IsValid)
        
            db.Entry(objapp).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        

        return View(machineSettings);

在页面上,我在下拉列表中显示了机器列表,何时进行更改并在下拉列表中选择另一台机器并单击保存。使用MachineSetting 对象调用Edit 方法。这里我的ModelState.IsValid 总是假的。

在调试模式下检查对象时,我从下拉列表中获取了MachineId,但未返回MachineName,因此如何避免MachineName 在此检查以使ModelState.IsValid 属性为真?

【问题讨论】:

确实需要MachineId,请检查是否可以删除所需属性 【参考方案1】:

尝试修复类

public class MachineSettings
            
        [Key]
        public int MachineSettingId  get; set; 

        [Required]
        public string Password  get; set; 

        [Required]
        public int ReferenceKeyLength  get; set; 

        [Required]
        public int? MachineId  get; set; 
      
        public virtual Machine Machine  get; set; 
    

public class Machine
    
        [Key]
        public int MachineId  get; set; 

        [Required]
        [Display(Name = "Machine Type")]
        public string MachineName  get; set;  

         public virtual ICollection<MachineSettings> MachineSettings  get; set;        
    

并为视图创建视图模型

public class MachineViewModel

public MachineSettings  MachineSettings get; set;
public IEnumerable<SelectListItem> Machines  get; set; 


和行动

public ActionResult Edit(MachineViewModel viewModel)

【讨论】:

【参考方案2】:

也许您应该为您的 ViewModel 使用特定的类。 ViewModel 用于 Views(UI) Controller 相互通信,通常是与持久性 (EF) 层不同的类。因此,您的 ViewModel 甚至不需要完整的 Machine 属性。可能是这样的:

public class MachineSettingsViewModel
        
    public int MachineSettingId  get; set;  // Only if you are using the ViewModel for edit

    [Required]
    public string Password  get; set; 

    [Compare("Password")]
    public string ConfirmPassword  get; set; 

    [Required]
    public int ReferenceKeyLength  get; set; 

    [Required]
    public int MachineId  get; set; 
  
    public IEnumerable<SelectListItem> Machines  get; set;  // Collection with the options for the machine selector. Must be filled in the controller from query to service or DB

ViewModel 可能包含仅在视图中使用的属性,或者是表单验证所需但在 DB 中不需要的属性。

在控制器“获取”操作中,您创建并填充视图模型,然后将其传递给视图,并在“发布”方法中验证视图模型并将其转换为要保存在数据库中的实体。

看看What is ViewModel in MVC?。这是对 ViewModel 与模型的更详细解释。

【讨论】:

以上是关于当模型具有外键时,ModelState.IsValid 为 false的主要内容,如果未能解决你的问题,请参考以下文章

Laravel:当表有两个外键时,为具有关系的数据库表播种

什么是 ModelState.IsValid 在 NerdDinner 的 ASP.NET MVC 中有效?

当有外键和主键时获得唯一项目?重复项(具有唯一弱键)?

Django模型:如何避免在使用来自同一个表的2个外键时引用相同的记录

Django - 删除外键时删除数据库条目

在 swift 3 中获取相关表