我在我的应用程序中的强类型视图中有以下代码:
<td> <label for="TriageStartDate">Triage Start:</label> <%= Html.TextBox("TriageStartDate",crit.TriageStartDate,new { maxlength = 10,size = 12 } )%> <%= Html.ValidationMessage("TriageStartDate","*") %> </td>
变量crit在ViewData中传递,并使用以下方法强制转换为视图中的强类型对象:
PatientSearchCriteria crit = (PatientSearchCriteria)ViewData["criteria"];
TriageStartDate属性是在对象上定义的字符串属性,如下所示:
public string TriageStartDate { get; set; }
我在业务对象中有一个验证例程,它检查此属性的无效日期.在我的控制器中调用验证例程,并且在控制器中,当找到无效日期时(例如“4/34/2009”),我将ModelError添加到ModelState.这应该会导致重新显示视图,并且还会显示验证摘要和消息.
但是,代码在Html.TextBox行崩溃时出现未处理的NullReferenceException.输入无效日期时代码只会崩溃,这可能无关紧要,因为该属性无论如何都是字符串,它应该只在文本框中显示无效日期.
有什么想法可能会发生在这里吗?我认为它可能是一个Html.Encode的东西,但有效的日期显示没有大惊小怪.当我在调试模式中断行时,我可以在TriageStartDate属性中看到值“4/34/2009”,并且暴击变量本身不为空,所以我想知道哪个对象是空的?
顺便说一句,堆栈跟踪的前几行看起来像这样:
[NullReferenceException: Object reference not set to an instance of an object.] System.Web.Mvc.HtmlHelper.GetModelStateValue(String key,Type destinationType) +63 System.Web.Mvc.Html.InputExtensions.InputHelper(HtmlHelper htmlHelper,InputType inputType,String name,Object value,Boolean useViewData,Boolean isChecked,Boolean setId,Boolean isExplicitValue,IDictionary`2 htmlAttributes) +519 System.Web.Mvc.Html.InputExtensions.TextBox(HtmlHelper htmlHelper,IDictionary`2 htmlAttributes) +34 System.Web.Mvc.Html.InputExtensions.TextBox(HtmlHelper htmlHelper,Object htmlAttributes) +62
这是我的验证码(可能不太漂亮).在业务对象中:
public override IEnumerable<ValidationError> GetValidationErrors() { // check for valid start date if (!String.IsNullOrEmpty(TriageStartDate)) { DateTime critStartDate; if (!DateTime.TryParse(TriageStartDate,out critStartDate)) yield return new ValidationError(String.Format("Invalid triage start date specified: {0}",TriageStartDate),"TriageStartDate"); } // check for valid end date if (!String.IsNullOrEmpty(TriageEndDate)) { DateTime critEndDate; if (!DateTime.TryParse(TriageEndDate,out critEndDate)) yield return new ValidationError(String.Format("Invalid triage end date specified: {0}",TriageEndDate),"TriageEndDate"); } // verify that end date follows start date if both are specified if (!String.IsNullOrEmpty(TriageStartDate) && !String.IsNullOrEmpty(TriageEndDate)) { DateTime startDate; DateTime endDate; if (DateTime.TryParse(TriageStartDate,out startDate) && DateTime.TryParse(TriageEndDate,out endDate)) { if (startDate > endDate) yield return new ValidationError("Triage start date must be before end date","_FORM"); } } yield break; }
在控制器中:
// validate search criteria if (!criteria.IsValid) { foreach (ValidationError ve in criteria.GetValidationErrors()) { ModelState.AddModelError(ve.PropertyName,ve.ErrorMessage); } }
谢谢你的任何线索!
感谢Craig的建议,我按如下方式更新了控制器代码,并且空引用异常消失了.该解决方案有效,但我不确定我理解的原因,因为用户试图输入的值已经存储在模型对象中,并且我在项目中有其他视图和控制器以相同的方式显示验证错误任何问题.但是,嘿,如果有效……
// validate search criteria if (!criteria.IsValid) { foreach (ValidationError ve in criteria.GetValidationErrors()) { ModelState.AddModelError(ve.PropertyName,ve.ErrorMessage); ModelState.SetModelValue(ve.PropertyName,form.ToValueProvider()[ve.PropertyName]); } }