0

我使用代码优先与EF。验证似乎失败的下拉列表与错误System.NullReferenceException:对象引用未设置为对象的实例。当我保存一条记录时,会发生这种情况,我故意将控件留空以测试验证。即使下拉列表本身有选择,也会发生。验证失败,下拉MVC

这里是我的部分观点:

<div class="editor"> 
    @Html.LabelFor(model => model.EmployeeID) 
    @Html.DropDownListFor(model => model.EmployeeID, new SelectList(Model.Employees, "Value", "Text")) 
    @Html.ValidationMessageFor(model => model.EmployeeID) 
</div> 

如果我用一个文本框验证工作:

<div class="editor"> 
    @Html.LabelFor(model => model.EmployeeID) 
    @Html.TextBoxFor(model => model.EmployeeID, new { style = "width: 250px;" }) 
    @Html.ValidationMessageFor(model => model.EmployeeID) 
</div> 

这里是我创建控制器操作:

public ActionResult Create() 
{ 
    var e = iEmployeeRepository.GetAll(); 
    var visitorLogViewModel = new VisitorLogViewModel 
    { 
     Employees = e.Select(x => new SelectListItem 
     { 
      Value = x.EmployeeID, 
      Text = x.EmployeeName 
     }) 
    }; 
    return View(visitorLogViewModel); 
} 

// 
// POST: /VisitorLogs/Create 

[HttpPost] 
public ActionResult Create(VisitorLog visitorlog) 
{ 
    if (ModelState.IsValid) { 
     iVisitorlogRepository.Add(visitorlog); 
     iVisitorlogRepository.Save(); 
     return RedirectToAction("Search"); 
    } else { 
     return View(); 
    } 
} 

我的视图模型:

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

    [Display(Name = "Visitor Name")] 
    public string VisitorName { get; set; } 

    [Display(Name = "Company Name")] 
    public string CompanyName { get; set; } 

    [Required(ErrorMessage = "Employee ID is required.")] 
    [Display(Name = "GB Employee")] 
    public string EmployeeID { get; set; } 

    [Display(Name = "Visit Reason")] 
    public string VisitReason { get; set; } 

    [Display(Name = "Time In")] 
    public DateTime TimeIn { get; set; } 

    [Display(Name = "Time Out")] 
    public DateTime TimeOut { get; set; } 

    [Display(Name = "GB Employee")] 
    public string EmployeeName { get; set; } 

    public IEnumerable Employees { get; set; } 
    public VisitorLog VisitorLog { get; set; } 
} 

而我的验证部分型号:

[MetadataType(typeof(VisitorLogMetaData))] 
public partial class VisitorLog 
{ 

} 

public class VisitorLogMetaData 
{ 
    [Required(ErrorMessage = "Visitor name is required.")] 
    [MaxLength(128)] 
    public string VisitorName { get; set; } 

    [Required(ErrorMessage = "Company name is required.")] 
    [MaxLength(128)] 
    public string CompanyName { get; set; } 

    [Required(ErrorMessage = "GB Employee is required.")] 
    [MaxLength(128)] 
    public string EmployeeID { get; set; } 

    [Required(ErrorMessage = "Visit reason is required.")] 
    [MaxLength(254)] 
    public string VisitReason { get; set; } 

    [Required(ErrorMessage = "Time in is required.")] 
    public DateTime TimeIn { get; set; } 

    [Required(ErrorMessage = "Time out reason is required.")] 
    public DateTime TimeOut { get; set; } 
} 

最后我的模型:

public partial class VisitorLog 
{ 
    public int Id { get; set; } 
    public string VisitorName { get; set; } 
    public DateTime TimeIn { get; set; } 
    public DateTime TimeOut { get; set; } 
    public string CompanyName { get; set; } 
    public string EmployeeID { get; set; } 
    public string VisitReason { get; set; } 

    // Navigation properties 
    [ForeignKey("EmployeeID")] 
    public virtual Employee Employee { get; set; } 
} 

我看了有在MVC剃刀关于DropDownListFor一个错误,但我不知道这是否适用于我的情况。我尝试了一些解决方案,但他们并没有为我工作。我正在使用4.5框架。

谢谢。

编辑:

一件事我注意到,当我提交页面和下拉元素上停止错误:

@Html.DropDownListFor(model => model.EmployeeID, new SelectList(Model.Employees, "Value", "Text")) 

在Model.Employees的型号为NULL,就像是失去其绑定页面时绑定。

回答

0

好吧,我对我的课做了一些有意义的改变。首先,我在我的控制器中更改了post方法。以前我是路过的模型后,我现在通过视图模型并将其映射到模型通过我的仓库保存前:

// 
    // POST: /VisitorLogs/Create 

    [HttpPost] 
    public ActionResult Create(VisitorLogViewModel visitorLogViewModel) 
    { 
     var e = iEmployeeRepository.GetAll(); 
     VisitorLog visitorLog = new VisitorLog(); 
     visitorLog.Id = visitorLogViewModel.Id; 
     visitorLog.VisitorName = visitorLogViewModel.VisitorName; 
     visitorLog.CompanyName = visitorLogViewModel.CompanyName; 
     visitorLog.EmployeeID = visitorLogViewModel.EmployeeID; 
     visitorLog.TimeIn = visitorLogViewModel.TimeIn; 
     visitorLog.TimeOut = visitorLogViewModel.TimeOut; 
     visitorLog.VisitReason = visitorLogViewModel.VisitReason; 
     visitorLogViewModel.Employees = new SelectList(e, "EmployeeID", "EmployeeName"); 

     if (ModelState.IsValid) 
     { 
      iVisitorlogRepository.Add(visitorLog); 
      iVisitorlogRepository.Save(); 
      return RedirectToAction("Search"); 
     } else { 
      return View(visitorLogViewModel); 
     } 
    } 

接下来,我不得不添加了“必需的”属性(验证)在视图模型:

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

    [Required(ErrorMessage = "Visitor name is required.")] 
    [MaxLength(128)] 
    [Display(Name = "Visitor Name")] 
    public string VisitorName { get; set; } 

    [Required(ErrorMessage = "Company name is required.")] 
    [MaxLength(128)] 
    [Display(Name = "Company Name")] 
    public string CompanyName { get; set; } 

    [Required(ErrorMessage = "GB Employee is required.")] 
    [MaxLength(16)] 
    [Display(Name = "GB Employee")] 
    public string EmployeeID { get; set; } 

    [Required(ErrorMessage = "Visit Reason is required.")] 
    [MaxLength(254)] 
    [Display(Name = "Visit Reason")] 
    public string VisitReason { get; set; } 

    [Display(Name = "Time In")] 
    public DateTime TimeIn { get; set; } 

    [Display(Name = "Time Out")] 
    public DateTime TimeOut { get; set; } 

    [Display(Name = "GB Employee")] 
    public string EmployeeName { get; set; } 

    public SelectList Employees { get; set; } 
} 

不知道这是最effcient方法,但一切正常了。如果有人看到这种方法有什么问题,请告诉我。