2011-11-14 14 views
14

Utworzyłem dość prosta strona z polem wyboru:wartości MV3 Duplikat Query String dla CheckBox (true, false dla Boolean)

@using (Html.BeginForm("MyController", "MyAction", FormMethod.Get)) 
{ 
    @Html.CheckBoxFor(x => x.MyCheckBox) 
    <input type="submit" value="Go!" />  
} 

URL jest wypełniona wartości MyCheckBox dwukrotnie !? Jako takie:

MyAction?MyCheckBox=true&MyCheckBox=false 

To tylko powiela wartość, jeśli pole jest prawdą. Jeśli ustawione na false, pojawi się tylko raz w ciągu zapytania.

Powyższy kod jest uproszczony, ponieważ mam kilka list rozwijanych i pole tekstowe w formularzu, które działa poprawnie. Nie sądzę, że jest coś niezwykłego w kodzie, który pominąłem w tym pytaniu.

Czy ktoś miał podobny problem z duplikatem parametrów łańcucha zapytania?

Odpowiedz

14

To zachowanie jest zgodne z projektem kontrolki checkbox. Standardowa kontrolka checkbox HTML nie przechodzi żadnej wartości, jeśli nie jest zaznaczona. Jest to nieintuicyjne. Zamiast tego, kontrolka pola wyboru ASP.Net ma 2 elementy, kontrolkę standardową, która jest widoczna, a także kontrolkę ukrytą o wartości "False".

Dlatego jeśli pole wyboru nie jest zaznaczone, zostanie przekazana jedna wartość: False.
Jeśli jest zaznaczone, będą dwie wartości: True i False. Dlatego trzeba użyć następującego kodu do sprawdzenia ważności w kodzie:

bool checkboxChecked = Request.QueryString["MyCheckBox"].Contains("True"); 
+2

Interesujące rzeczy, ale co, jeśli masz na myśli czystość adresu URL? Wygląda trochę głupio, mając ten parametr dwa razy !? – pfeds

+0

Może być nieestetyczny, ale 99% Twojej bazy użytkowników nie zrozumie tego. Jeśli naprawdę martwisz się o czystość swoich adresów URL, możesz przekazać dane pocztą i utworzyć konkretną trasę dla formularza. –

+0

Tak, masz rację. Zostawię to jako GET i przestanę być tak pedantyczny. Wielkie dzięki Rory. – pfeds

3

Akceptowane odpowiedź jest poprawna jednak w moim przypadku w ostatnich rozwoju zachowanie MVC jest mylące.

Urządzenia MVC Html.CheckBox(...) i Html.CheckBoxFor(...) generują dodatkowe wejście "typ = ukryty" o tym samym identyfikatorze co kontrolka wyboru, prowadząc do zduplikowanych parametrów adresu URL. Mam ten problem, po prostu w tym znak się pożądany sposób następujący:

@if(checkTrue){ 
    <input type="checkbox" id="MyCheckBox" name="MyCheckbox" checked="checked"> 
}else{ 
    <input type="checkbox" id="MyCheckBox" name="MyCheckbox"> 
} 

byłoby lepiej opakowane UPIN pomocnika do wykorzystania w miejsce kodu MVC więc sprawdzić wartość jest zamknięty.

W ramach mojej aplikacji kontroler przechowuje zestawy parametrów zapytania za pomocą zarówno wtrysku formularza, jak i iniekcji łącza za pomocą helperów w celu zachowania stanu (np. Kontroli stronicowania/filtrowania) po kliknięciu, aby nawigować w obrębie tego samego zakresu kontrolera. W wyniku tej funkcji element pola wyboru jest zawsze cofany do wartości false, jeśli używane są standardowe helpery MVC. To dobrze, że zauważyłem i nie traciłem czasu na ten błąd.

+3

Twoja uwaga nie jest prawidłowa, ASP.NET MVC generuje dodatkowe wejście typu _hidden_, a nie _text_ podczas korzystania z helperów CheckBoxFor. Zobacz http://stackoverflow.com/questions/2697299/asp-net-mvc-why-is-html-checkbox-generating-an-additional-hidden-input – janv8000

+0

@ janv8000 Masz rację, poprawiłem swój błąd dzięki. – kas

1

W moim modelu, miałem kolekcję wyboru tak:

public class PrerequisitesViewModel 
{ 
    public List<StudentPrerequisiteStatusViewModel> PrerequisiteStatuses { get; set; } 
} 

public class StudentPrerequisiteStatusViewModel 
{ 
    public long Id { get; set; } 

    public string Name { get; set; } 

    public bool IsSelected { get; set; } 
} 

W celu uzyskania wszystko, aby związać poprawnie, musiałem faktycznie konwertować wartości z kwerendy i przetworzyć je ręcznie za pomocą następujących kod:

// fix for how MVC binds checkboxes... it send "true,false" instead of just true, so we need to just get the true 
for (int i = 0; i < model.PrerequisiteStatuses.Count(); i++) 
{ 
    model.PrerequisiteStatuses[i].IsSelected = bool.Parse((Request.QueryString[$"PrerequisiteStatuses[{i}].IsSelected"] ?? "false").Split(',')[0]); 
} 

Niestety, to działa, ale nie mogę uwierzyć, że jest to konieczne w MVC! Mamy nadzieję, że ktoś inny zna lepsze rozwiązanie.

+0

Zgadzam się, to nie powinno być konieczne w MVC! dla przykładu wystarczy kwerenda z rozdzieloną listą aktywnych pól wyboru. mycheckboxlist = 1,5,6,10 – andrew