【问题标题】:validation failing on dropdown MVC下拉 MVC 验证失败
【发布时间】:2012-12-04 15:26:55
【问题描述】:

我在 EF 中使用代码优先。下拉列表中的验证似乎失败,并出现错误 System.NullReferenceException: Object reference not set to an instance of an object。当我保存记录并故意将控件留空以测试验证时,就会发生这种情况。即使下拉列表本身有选择,也会发生这种情况。

这是我的部分观点:

<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 中的 Model 为 null,就像提交页面时它失去了绑定一样。

【问题讨论】:

    标签: validation ef-code-first html.dropdownlistfor asp.net-mvc-viewmodel


    【解决方案1】:

    好的,我对我的课程做了一些根本性的改变。首先,我更改了控制器中的 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; }
    }
    

    不确定这是否是最有效的方法,但现在一切正常。如果有人发现此方法有问题,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-09
      • 2011-05-31
      • 1970-01-01
      相关资源
      最近更新 更多