2009-05-05 27 views
8

Tôi có đoạn code sau đây trong một Xem mạnh mẽ-gõ trong ứng dụng của tôi:NullReferenceException Vấn đề với ASP.NET MVC Textbox HtmlHelper

<td> 
<label for="TriageStartDate">Triage Start:</label> 
<%= Html.TextBox("TriageStartDate", crit.TriageStartDate, new { maxlength = 10, size = 12 })%> 
<%= Html.ValidationMessage("TriageStartDate", "*") %> 
</td> 

Biến crit được thông qua tại ViewData và được đúc vào một strongly- đối tượng đánh máy trong giao diện sử dụng:

PatientSearchCriteria crit = (PatientSearchCriteria)ViewData["criteria"];  

các TriageStartDate tài sản là một tài sản chuỗi xác định trên đối tượng như vậy:

public string TriageStartDate { get; set; } 

Tôi có quy trình xác thực trong đối tượng kinh doanh kiểm tra thuộc tính này cho các ngày không hợp lệ. Các thói quen xác nhận được gọi là trong bộ điều khiển của tôi, và trong bộ điều khiển tôi thêm một ModelError để ModelState khi một ngày không hợp lệ được tìm thấy (ví dụ "4/34/2009"). Điều này sẽ dẫn đến lượt xem được hiển thị lại và tóm tắt xác thực cũng như thông báo được hiển thị.

Tuy nhiên, mã bị treo trên dòng Html.TextBox với NullReferenceException chưa được giải quyết. Mã số chỉ bị lỗi khi nhập ngày không hợp lệ, điều này có lẽ không quan trọng vì thuộc tính là chuỗi và sẽ chỉ hiển thị ngày không hợp lệ trong hộp văn bản.

Bất kỳ ý tưởng nào có thể xảy ra ở đây? Tôi nghĩ rằng nó có thể là một điều Html.Encode, nhưng ngày hợp lệ hiển thị mà không có một fuss. Khi tôi phá vỡ dòng đó trong chế độ gỡ lỗi, tôi có thể thấy giá trị "4/34/2009" trong thuộc tính TriageStartDate, và biến crit không phải là null, vì vậy tôi tự hỏi đối tượng IS rỗng là gì?

BTW, vài dòng đầu tiên của ngăn xếp dấu vết giống như thế này:

[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 

Đây là mã xác nhận của tôi (mà có thể không được khá). Trong các đối tượng kinh doanh:

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; 
} 

trong bộ điều khiển:

// validate search criteria 
    if (!criteria.IsValid) 
    { 
     foreach (ValidationError ve in criteria.GetValidationErrors()) 
     { 
      ModelState.AddModelError(ve.PropertyName, ve.ErrorMessage); 
     } 
    } 

Thanks cho bất kỳ manh mối!


Nhờ đề xuất của Craig, tôi đã cập nhật mã điều khiển như sau và ngoại lệ tham chiếu null đã biến mất. Giải pháp đã làm việc, nhưng tôi không chắc tôi hiểu lý do, vì giá trị mà người dùng cố gắng nhập đã được lưu trữ trong đối tượng mô hình và tôi có các chế độ xem và bộ điều khiển khác trong dự án đang hiển thị lỗi xác thực theo cách tương tự mà không bất kỳ vấn đề nào. Nhưng, này, nếu nó hoạt động ...

// 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]); 
     } 

    } 
+0

đặt mã xác nhận của bạn, tôi nghĩ vấn đề là có –

Trả lời

9

Sau khi bạn gọi AddModelError bạn cần gọi SetModelValue. Điều đó nên sửa tham chiếu null.

+0

Craig, cảm ơn cho câu trả lời, nhưng tôi không thể tìm thấy bất kỳ phương pháp SetAttempedValue trên bất kỳ của các đối tượng trong bộ điều khiển hoặc xem. Tôi thấy SetModelValue, nhưng nó không phải là rõ ràng với tôi làm thế nào để sử dụng này - hoặc thậm chí nếu tôi nên - đưa ra tham số thứ hai của loại ValueProviderResult, mà tôi không biết làm thế nào để xây dựng. Mô hình thực sự chứa giá trị đã cố gắng nhập bởi người dùng, vì vậy tôi không chắc chắn vị trí này để lại cho tôi. Có lẽ sâu dưới bao gồm một nơi nào đó ASP.NET MVC đang cố gắng để chuyển đổi giá trị cho một ngày và có một vấn đề ?? –

+0

Một cách là với Form.ToValueProvider() ... –

+0

Cảm ơn, Craig. Tôi đã cập nhật mã của mình để chứa SetModelValue bằng phương thức Form.ToValueProvider tạo ra ValueProviderResult và điều này đã sửa lỗi ngoại lệ tham chiếu null. Tôi vẫn còn bối rối, nhưng mã của tôi hoạt động ... :-) –

1

Tôi bắt gặp vấn đề này khi tôi đang nhập một câu hỏi/vấn đề gần như giống hệt nhau. (nghĩa là, hiển thị chế độ xem của tôi đã gây ra một NullReferenceException bí ẩn để được ném khi giá trị của người dùng không được xác thực trên một trường cụ thể không được xác thực trên một trường cụ thể. cho phép HtmlHelper thực hiện công việc.

Ví dụ: <%= Html.TextArea("FieldName", Model.FieldName) %> sẽ ném một ngoại lệ, nhưng <textarea id="FieldName" name="FieldName"><%= Model.FieldName ></textarea> sẽ hoạt động hoàn toàn tốt.

Cảm ơn bạn đã đăng câu hỏi ban đầu từ bây giờ tôi sẽ phải làm một số chi tiết nhìn vào SetModelValue để xem cái nào trong hai phương pháp là giải pháp tốt hơn ...

Các vấn đề liên quan