NullReferenceException ASP.NET MVC文本框HtmlHelper的问题

时间:2009-05-05 20:04:02

标签: asp.net-mvc

我在我的应用程序中的强类型视图中有以下代码:

<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”,并且暴击变量本身不为空,所以我想知道哪个对象是空的?

BTW,堆栈跟踪的前几行如下所示:

[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, String name, Object value, IDictionary`2 htmlAttributes) +34
   System.Web.Mvc.Html.InputExtensions.TextBox(HtmlHelper htmlHelper, String name, Object value, 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]);
        }

    }

3 个答案:

答案 0 :(得分:9)

调用AddModelError后,您需要调用SetModelValue。这应该修复空引用。

答案 1 :(得分:1)

当我输入一个几乎相同的问题/问题时,我遇到了这个问题。 (即,当用户的值在特定字段上的验证失败时,渲染我的视图会导致引发神秘的NullReferenceException。

我发现的另一种解决方法是在视图中显式生成Html,而不是让HtmlHelper完成工作。

例如: <%= Html.TextArea("FieldName", Model.FieldName) %>会抛出异常,但是 <textarea id="FieldName" name="FieldName"><%= Model.FieldName ></textarea>可以完美地运作。

感谢您发布原始问题,因为现在我将不得不进一步研究SetModelValue,看看这两种方法中的哪一种是更好的解决方案......

答案 2 :(得分:1)

我发现有助于解释此问题的链接 http://forums.asp.net/t/1380609.aspx