2009-03-18 10 views
14

Szalony problem ze złożeniem wartości w Html.Checkbox w ASP.NET MVC RCMVC Html.CheckBox i forma przedstawienia emisyjnej

Niektóre wartości nie są po prostu przyjść do Request.Params

Na moim formularzu mam ten wiersz wewnątrz cyklu:

<%=Html.CheckBox("cb" + p.Option.Id, p.Option.IsAllowed, new { value = 6 })%>

i renderuje do następnej:

<input checked="checked" id="cb17" name="cb17" type="checkbox" value="6" /> 
<input name="cb17" type="hidden" value="false" /> 

    <input checked="checked" id="cb18" name="cb18" type="checkbox" value="6" /> 
<input name="cb18" type="hidden" value="false" /> 

    <input id="cb19" name="cb19" type="checkbox" value="6" /> 
<input name="cb19" type="hidden" value="false" /> 

    <input id="cb20" name="cb20" type="checkbox" value="6" /> 
<input name="cb20" type="hidden" value="false" /> 

    <input checked="checked" id="cb21" name="cb21" type="checkbox" value="6" /> 
<input name="cb21" type="hidden" value="false" /> 

Po wysłaniu formularza jestem coś takiego:

Form.Params["cb17"] = {6, "false"} 
Form.Params["cb18"] = {6, "false"} 
Form.Params["cb19"] = {"false"} 
Form.Params["cb20"] = {"6,false"} 
Form.Params["cb21"] = {"false"} 

W ciągu żądanie Niektóre params wyświetlane są dwa razy (normalnej sytuacji), a niektóre tylko jeden raz (tylko wartość pola ukrytego). Wygląda na to, że nie zależy od tego, czy pole wyboru było zaznaczone czy nie, czy zmieniła się wartość ...

Czy ktoś miał do czynienia z taką sytuacją? Jak mogę obejść?

Odpowiedz

16
<% using(Html.BeginForm("Retrieve", "Home")) %>//Retrieve is the name of the action while Home is the name of the controller 
     <% { %> 
    <%foreach (var app in newApps)    { %> 
    <tr> 
     <td><%=Html.CheckBox(""+app.ApplicationId)%></td>  

    </tr> 
<%} %> 
<input type"submit"/> 
<% } %> 

aw kontrolerze

List<app>=newApps; //Database bind 
for(int i=0; i<app.Count;i++) 
{ 

    var checkbox=Request.Form[""+app[i].ApplicationId]; 
    if(checkbox!="false")// if not false then true,false is returned 
} 

powodem sprawdzić za fałszywe, ponieważ pomocnika Html CheckBox robi jakiś zakręcony rzeczą dla wartości prawdziwej

Prawdziwy zwrot jako:

it makes the string read "true, false" 

więc można pomyśleć, że to dwie wartości, ale to tylko jeden i oznacza prawdziwe

fałszywych zwrotów jak:

it makes the string read "false" 
+0

Twoje rozwiązanie jest całkiem dobre. Ale myślę o przesyłaniu formularza bezstanowego. W odniesieniu do Twojego przykładu nie wiem, ile obiektów mam w aplikacji [i] –

+0

Właśnie zaktualizowałem. aplikacja [i] iterowała przez identyfikatory formularza, które znajdowały się na stronie. Gdy pole wyboru jest dynamicznie powiązane, musisz znaleźć identyfikator w DB, a następnie porównać każdą wartość z formularza – TStamper

+1

Czy istnieje odpowiednie wyjaśnienie, dlaczego tak się dzieje? ? dlaczego "prawda, fałsz" dla prawdziwości? – chakrit

10

Jest to właściwie sposób, w jaki powinien działać zgodnie ze specyfikacją.

Nie ma nic wspólnego z ASP.NET MVC, ale gdy pole wyboru nie jest zaznaczone, to jest nie zawarte w kolekcji POST.

Otrzymujesz dwie wartości, ponieważ masz zarówno pole wyboru, jak i dane wejściowe o tej samej nazwie (a te, do których masz dwie wartości, najprawdopodobniej te, z zaznaczonymi polami wyboru).

Edit: specifications z W3C

+0

tak, teraz widzę, co jest regułą wyjaśnienia takiego zachowania –

+0

Co? to nie jest prawda ... W mvc pola wyboru są renderowane inaczej, niż zwykłe pole wyboru html. – TStamper

+3

Tak, są renderowane jako 2 wejścia. Ale to nie zmienia faktu, że pole wyboru NIE jest częścią wartości POST, chyba że zaznaczone jest to, co otrzymujesz patrząc na Form.Params []. Jeśli określisz bool jako parametr dla twojego działania, to tak będzie działało jako "oczekiwane". Ale to "magia" MVC. – veggerby

2

Bez konieczności zadawania bazy danych o identyfikatorach po formy złożeniem/przed zapisaniem (tryb bezpaństwowy) Wygenerowałem taki kod:

foreach (string key in Request.Form) 
    { 
     var checkbox = String.Empty; 
     if (key.StartsWith("cb")) 
     { 
      checkbox = Request.Form["" + key]; 

      if (checkbox != "false") 
      { 
       int id = Convert.ToInt32(key.Remove(0, 2)); 
      } 
     } 
    } 

Dziękuję wam, za pomoc w rozwiązaniu tego problemu !

0

Używam tego:

public struct EditedCheckboxValue 
{ 
    public bool Current { get; private set; } 

    public bool Previous { get; private set; } 

    public bool Changed { get; private set; } 

    public EditedCheckboxValue(System.Web.Mvc.FormCollection collection, string checkboxID) : this() 
    { 
     string[] values = collection[checkboxID].Split(new char[] { ',' }); 
     if (values.Length == 2) 
     { // checkbox value changed, Format: current,old 
      Current = bool.Parse(values[0]); 
      Previous = bool.Parse(values[1]); 
      Changed = (Current != Previous); 
     } 
     else if (values.Length == 1) 
     { 
      Current = bool.Parse(values[0]); 
      Previous = Current; 
      Changed = false; 
     } 
     else 
      throw new FormatException("invalid format for edited checkbox value in FormCollection"); 
    } 
} 

a następnie nazwać tak:

EditedCheckboxValue issomething = new EditedCheckboxValue(collection, "FieldName"); 
instance.IsSomething = issomething.Current; 
Powiązane problemy