2009-04-06 13 views
16

I HAVER prostą listę przycisku radiowego na mojej stronie, że render z następujących moim zdaniem:ASP.NET MVC Html.RadioButton Wyjątek

<label for="gender">Gender</label> 
<%= Html.RadioButton("gender", 1) %> Male 
<%= Html.RadioButton("gender", 2) %> Female 
<%= Html.ValidationMessage("gender") %> 

Zauważ, że gdy użytkownik początkowo widzi to wejście, ani przycisk jest zaznaczona. Walidacja ma na celu zmuszenie ich do wybrania i nieprzyjęcia wartości domyślnej. Dlatego te dwa przyciski radiowe są zobowiązane do wartości pustych int nieruchomości w moim modelu zadeklarowanej jako:

public int? gender { get; set; } 

Więc jeśli nie wybrać przycisk i przesłać na stronę, właściwość płci będzie zerowa wskazuje, że nie wybrał. Poniższy walidacja nazywany jest przez kontroler podczas postu:

if (!gender.HasValue) 
    ModelState.AddModelError("gender", "gender required"); 

Ale, jeśli uwierzytelnienie nie powiedzie się (nie wyboru), a następnie na etapie renderowania, następujący wyjątek jest generowany przez framework MVC:

System.NullReferenceException was unhandled by user code 
    Message="Object reference not set to an instance of an object." 

Szukając rozwiązania tego problemu, zauważyłem, że kilku miało ten problem. Używam ASP.NET MVC 1.0. Znalazłem to miejsce w kodzie, w którym ten błąd jest generowany za pomocą .NET Reflectora.

Pytanie, jak to zrobić, aby działało poprawnie?

EDIT: aby dodać StackTrace:

System.NullReferenceException was unhandled by user code 
    Message="Object reference not set to an instance of an object." 
    Source="System.Web.Mvc" 
    StackTrace: 
     at System.Web.Mvc.HtmlHelper.GetModelStateValue(String key, Type destinationType) 
     at 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) 
     at System.Web.Mvc.Html.InputExtensions.RadioButton(HtmlHelper htmlHelper, String name, Object value, Boolean isChecked, IDictionary`2 htmlAttributes) 
     at System.Web.Mvc.Html.InputExtensions.RadioButton(HtmlHelper htmlHelper, String name, Object value, IDictionary`2 htmlAttributes) 
     at System.Web.Mvc.Html.InputExtensions.RadioButton(HtmlHelper htmlHelper, String name, Object value) 
     at ASP.views_vbs_register_aspx.__RenderregisterContent(HtmlTextWriter __w, Control parameterContainer) in c:\Users\David\Documents\BellevueProject\Bellevue\BellevueTeachers\Forms\Views\VBS\Register.aspx:line 42 
+0

Czy można wyświetlić ślad stosu? lub linii, w której wystąpił błąd? – tvanfosson

Odpowiedz

11

prostu próbowałem coś sprawia, że ​​tę pracę. Problem nie występuje, jeśli nie wykonuję kroku sprawdzania poprawności, ale oczywiście potrzebuję sprawdzania poprawności. To dało mi klucz do rozwiązania.

Metoda ValidationMessage HtmlHelper przyjmuje argument łańcuchowy, który jest nazwą sprawdzanego obiektu właściwości lub modelu. Właśnie zmienił tę nazwę jako „gender2” w następujący sposób:

<label for="gender">Gender</label> 
<%= Html.RadioButton("gender", 1) %> Male 
<%= Html.RadioButton("gender", 2) %> Female 
<%= Html.ValidationMessage("gender2") %> 

I zmienił kod weryfikacyjny, aby odnieść się do tej nowej nazwy (mimo, że nieruchomość nie istnieje, to nadal działa):

if (!gender.HasValue) 
    ModelState.AddModelError("gender2", "gender required"); 

Ta funkcja działa zgodnie z oczekiwaniami.

Byłbym przekonany, że drugi powinien zadziałać, ale jest to proste obejście i dokumentuję to tutaj.

EDYTOWANIE: Przy okazji próbowałem zmienić właściwość płci na ciąg zamiast z wartością zerową int i pojawia się ten sam dokładny problem.

Podczas pracy nadal używa się innej nazwy klucza do komunikatu walidacyjnego.

1

Możesz spróbować zmienić płeć na ciąg (M/F) zamiast na int i sprawdzić, czy to działa.

Jeśli absolutnie musisz mieć to jako int, zawsze możesz tłumaczyć na końcu.

private int? gender { get; set; } 
public string displayGender 
{ 
    get 
    { 
     return this.gender.HasValue 
       ? (this.gender.Value == 1 ? "M" : "F") 
       : null; 
    } 
    set 
    { 
     this.gender = null; 
     if (value == "M") 
      this.gender = 1; 
     else if (value == "F") 
      this.gender = 2; 
    } 
} 

<label for="gender">Gender</label> 
<%= Html.RadioButton("displayGender", "M") %> Male 
<%= Html.RadioButton("displayGender", "F") %> Female 
<%= Html.ValidationMessage("displayGender") %> 

bazowa na Twój komentarz, można dodać:

<%= Html.RadioButton("displayGender", 
        string.Empty, 
        true, // this is the default 
        new { @style = "display: none;" }) %> 

To zapewni, że displayGender zostanie wysłane z powrotem (nie zawsze będzie wybrany radio) i myślę, że wartość będzie ciąg .Empty zamiast odwołania zerowego. Jeśli to działa, możesz spróbować przełączyć się z powrotem na wartość n.

+0

To samo dzieje się z ciągiem w tym samym miejscu. Nawet łańcuch znaków jest pusty, gdy nie ma wyboru. Błąd nie występuje, jeśli nie sprawdzam poprawności. – davcar

+0

Spróbuj utrzymując go łańcuch i dodać „ukryty” radio, że ma wartość string.empty. Zaktualizuję mój przykład. Myślę, że nie spodziewa się, że przycisk radio może mieć wartość null, więc nie sprawdza przed próbą go przekonwertować. – tvanfosson

+0

Ach, widzę, ciekawe mieć ukryty przycisk domyślny radiową. Dzięki za pomysł. – davcar

1

spróbuj dodać następujący wiersz kodu po ModelState.AddModelError():

ModelState.SetModelValue("gender", ValueProvider["gender"]); 
7

ten jest bardzo podobny, jeśli nie równa emisji checkbox: Metoda Html.Checkbox() pomocnika generuje ukryte pole z fałszywym wartość. Jeśli tego pola nie ma, przeglądarka nie wyśle ​​żadnych danych dla niezablokowanych ramek.

RadioButton jednak ma mieć wartość, a możliwe wartości może być więcej niż jeden. W tym przypadku nie jest tak łatwo poradzić sobie z przypadkiem braku selekcji, co, jak sądzę, jest powodem, dla którego tak nie jest.

Rozwiązaniem dla mnie było, aby dodać ukryte pole w następujący sposób:

<%= Html.RadioButton("gender", 1) %> Male 
<%= Html.RadioButton("gender", 2) %> Female 
<%= Html.Hidden("gender", null) %> 
1

Jeśli chcesz drutu w walidacji po stronie klienta. Przejdź pomocnika HTML i ręcznie napisać swoje radio, dając im atrybutów dla danych i danych-Val-Val-wymagane. Lubię to.

<input type="radio" name="displayGender" id="displayGender" value="1" data-val="true" data-val-required ="The gender field is required."/> 
    <input type="radio" name="displayGender" id="displayGender" value="2" data-val="true" data-val-required ="The gender field is required."/>