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方法,但一切正常了。如果有人看到這種方法有什麼問題,請告訴我。