【问题标题】:ModelState.IsValid is false when model has a foreign key当模型具有外键时,ModelState.IsValid 为 false
【发布时间】: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,请检查是否可以删除所需属性

标签: c# asp.net-mvc .net-core entity-framework-core model-binding


【解决方案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 与模型的更详细解释。

    【讨论】:

      猜你喜欢
      • 2016-12-27
      • 2019-05-20
      • 1970-01-01
      • 2023-03-29
      • 2010-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-10
      相关资源
      最近更新 更多