2009-07-14 16 views
30

なぜ世界で行ない:なぜASP.NET MVC Html.CheckBoxは同じ名前の2つのINPUTを出力しますか?

<%= Html.CheckBox("ForSale", Model.Product.ForSale)%> For Sale 

結果、次のHTMLで:私はボックスとアクセスRequest.Form["ForSale"]をチェックするたびに

<input id="ForSale" name="ForSale" type="checkbox" value="true" /> 
<input name="ForSale" type="hidden" value="false" /> 
For Sale 

は今、私は"true,false"のとんでもない答えを得ます。私はそれを解析するはずですか?

この隠しフィールドは、他のHtmlHelperコントロールには表示されません。そのため、CheckBoxではどうしてですか?

この愚かな「機能」をオフにするにはどうすればよいですか?HtmlHelperはその有用性を凌駕しましたか?

更新

以下の答えから、この背後にあるいくつかのロジックがあるようです。

public static bool GetCheckBoxValue(this System.Web.HttpRequestBase req, 
             string name) { 
     return Convert.ToBoolean(req.Form.GetValues(name).First()); 
    } 
+9

Request.Formを使用している場合は、間違っている可能性があります。 –

+1

+1 - 先日、この問題に遭遇しました。彼らが役に立つようにしようとしていたようだが、ちょうどチェックボックスがどのように働くべきかを実際に知っている私たちの人たちを悩ませた。 –

+2

@mgrovesの心は私がおそらく間違っていることを私に教えてくれる答えを投稿していますか? –

答えて

37

それはそれはオフになっている場合が含まれるフィールドを強制的に:私はそれについて考える必要はありませんので、私は(EU-GE-NEは、@のおかげで)少し拡張メソッドを用意しました。チェックボックスのチェックを外すと、ページの一部として送信されません。チェックされている場合にのみ送信され、trueの値があります。非表示フィールドは常に送信されるため、非表示フィールドではチェックボックスがオフの場合falseが送信されます。

+0

だから私は文字列を解析するはずですか? –

+3

文字列を解析する必要はありません。アクション内で直接Requestオブジェクトを使用しないでください。アクションメソッドのパラメータの1つとしてブール値を使用し、すべてがあなたのために処理されます – CodeClimber

+1

展開する:アクションメソッドのシグネチャが 'public ActionResult b(bool b = false) 'の場合、余分に生成された' 'は違いはありません。アクションメソッドのシグネチャが 'public ActionResult b(bool b = true)'または 'public ActionResult b(bool b)'である場合、チェックボックスが含まれていても特定のフォームでチェックされていなければ 'b'が' false'に設定され、チェックボックスを含まないフォームでは 'b'は' true'にセットされ、エラーは生成されます。この 'Html.CheckBox()'の振る舞いは、 ''未チェック ''が常に 'false'に正しくマップされ、フォームがアクションメソッドと一致することを保証します。 – binki

2

CheckBoxがチェックされていない場合、フォーム提出には含まれません。したがって、この「機能」はすべてのCheckBoxの結果を提供します。チェックされていないものは単に「偽」になります。

私は独自に動作するチェックボックスヘルパ関数を別々に実装しています。ほとんどの場合、私はちょうど真偽を望んでいませんが、チェックボックスの値のコレクションです。アクションを実行するIDで特定のアイテムを選択するのに最適です。私はチェックされていない項目もリストに入れたくない。

html拡張機能のソースコードを見て、同様の構造を使って独自のCheckBoxメソッドを作成することができます。

http://aspnet.codeplex.com/sourcecontrol/changeset/view/23011?projectName=aspnet#288010

私は私を投稿するだろうが、私は、標準のHtmlHelperのクラスを使用していないので、それはおそらくもっと混乱することでしょう。 CheckBox関数に値パラメータを追加して、 "true"または "false"の代わりに特定のid値を使用できるようにしました。

2

これで、チェックボックスをオンにしてRequest.Form ["ForSale"]にアクセスすると、「true、false」のばかげた答えが得られます。私はそれを解析するはずですか?

これを試してみてください:

var ForSale = Convert.ToBoolean(Request.Form.GetValues("ForSale").First()); 

更新:

何次MVCはREVERS "は偽、真" の順番で、それは値を返す構築であれば? ... - 首謀

var ForSale = Request.Form.GetValues("ForSale") 
    .Select(x => x.ToUpperInvariant()).Contains("TRUE"); 

// or 

// FormatException can be thrown from Convert.ToBoolean() 
var ForSale = Request.Form.GetValues("ForSale") 
    .Select(x => Convert.ToBoolean(x)).Contains(true); 
+0

次のMVCビルドで逆の順序で「false、true」の値を返した場合はどうなりますか?これは実用的だが信頼性の高いソリューションではない。だから、私は組み込みのヘルパーを放棄し、自分自身をしました。 – User

+1

@フランク・クルーガー - MVC2にはない –

3

は、ここで私は私のアプリケーションのいずれかでそれをやった方法です。挫折しましたが、うまくいくようです。

public virtual ActionResult Edit(int id, FormCollection values) 
{ 
    SomeObject dbData = _repository.GetSomeObject(id); 

    try 
    { 
     UpdateModel(dbData); 
     if (values.GetValues("CheckBoxId").Contains("true")) 
      dbData.SomeBooleanProperty = true; 
     else 
      dbData.SomeBooleanProperty = false; 

     _repository.Save(); 

     Session["Success"] = "Successfully edited the part."; 
     return RedirectToAction("Index"); 
    } 
    catch 
    { 
     // Handle validation errors here 
     return View(new SomeObjectFormViewModel(dbData)); 
    } 
} 

これが役立ちます。あなたがフォローアップの質問を持っている場合は、コメントを残して、私はそれに応じて私の答えを更新します。

0

は、私はきれいな解決策を行うことだと思います

request.form["chkBoxes"].replace("false","").split(new char[] {','}, stringsplitoptions.removeemptyentries);

0

を試してみてください。

(bool)formCollection["key"].ConvertTo(typeof(bool)) 
3

私は別のアプローチを取った:

はHtml.CheckBoxForまたはHTMLを使用しないでください。チェックボックスをレンダリングするCheckBoxヘルパーメソッドですが、通常のhtmlを使用してレンダリングします:

<input id="ShowOther" name="ShowOther" value="<%=Model.ShowOther %>" type="checkbox" <% if (Model.ShowOther) { %>checked="checked"<% } %> /> 

そして、チェックボックスがチェックされている/選択されていない場合、値を設定するjQueryスクリプトを追加しました。

<script type="text/javascript"> 
    $(function() { 
     $('#ShowOther').click(function() { 
      var checked = $(this).attr('checked'); 
      if (checked != undefined) 
       $(this).val(true); 
      else 
       $(this).val(false); 
     }); 
    }); 
</script> 

限り、私はこれをテストすることができて、正しいが常にコントローラに送信され、そしてとのこれ以上の問題「真偽」ているようです。

関連する問題