246

注意: この質問は 9 年以上前のものです。

ここでの多くの回答は現在廃止されているため、新しい質問を検索するか、以下の回答を検索して特定のバージョンの MVC を探すことをお勧めします。

お使いのバージョンで機能する回答が見つかった場合は、回答に使用している MVC のバージョンが含まれていることを確認してください。
(元の質問は以下から始まります)


これは私には少し奇妙に思えますが、私が知る限り、これがあなたのやり方です。

オブジェクトのコレクションがあり、ユーザーに 1 つまたは複数のオブジェクトを選択してもらいます。これは、「チェックボックス付きのフォーム」と言っています。私のオブジェクトには「選択された」という概念がありません (wcf 呼び出しを逆シリアル化することによって形成された基本的な POCO です)。だから、私は次のことをします:

public class SampleObject{
  public Guid Id {get;set;}
  public string Name {get;set;}
}

ビューで:

<%
    using (Html.BeginForm())
    {
%>
  <%foreach (var o in ViewData.Model) {%>
    <%=Html.CheckBox(o.Id)%>&nbsp;<%= o.Name %>
  <%}%>
  <input type="submit" value="Submit" />
<%}%>

そして、コントローラーでは、これがユーザーがチェックしたオブジェクトを把握する唯一の方法です。

public ActionResult ThisLooksWeird(FormCollection result)
{
  var winnars = from x in result.AllKeys
          where result[x] != "false"
          select x;
  // yadda
}

まず第一に、そして第二に、ユーザーがチェックした項目について、FormCollection はその値を単に true ではなく「true false」としてリストします。

明らかに、私は何かが欠けています。UpdateModel()これは、html フォーム内で操作されるコレクション内のオブジェクトが、ModelBinder を使用または介して更新されることを念頭に置いて構築されていると思います。

しかし、私のオブジェクトはこのように設定されていません。これしか方法がないということですか?それを行う別の方法はありますか?

4

22 に答える 22

262

Html.CheckBox は奇妙なことをしています。結果のページでソースを表示<input type="hidden" />すると、各チェックボックスの横に生成されていることがわかります。これは、各フォーム要素に表示されている「真偽」値を説明しています。

これを試してみてください。ASP.NET MVC Beta で確実に動作します。私は試したばかりです。

Html.CheckBox() を使用する代わりに、これをビューに入れます。

<% using (Html.BeginForm("ShowData", "Home")) {  %>
  <% foreach (var o in ViewData.Model) { %>
    <input type="checkbox" name="selectedObjects" value="<%=o.Id%>">
    <%= o.Name %>
  <%}%>
  <input type="submit" value="Submit" />
<%}%>

チェックボックスはすべて と呼ばれselectedObjectsvalue各チェックボックスの は対応するオブジェクトの GUID です。

次に、次のコントローラー アクション (または、Response.Write() の代わりに役立つ何かを行う同様のもの) に投稿します。

public ActionResult ShowData(Guid[] selectedObjects) {
    foreach (Guid guid in selectedObjects) {
        Response.Write(guid.ToString());
    }
    Response.End();
    return (new EmptyResult());
}

この例では、チェックしたボックスの GUID を書き込むだけです。ASP.NET MVC は、選択したチェックボックスの GUID 値をGuid[] selectedObjectsパラメーターにマップし、Request.Form コレクションの文字列をインスタンス化された GUID オブジェクトに解析します。

于 2008-10-20T21:49:11.987 に答える
95

HtmlHelper は非表示の入力を追加して、Unchecked ステータスについてコントローラーに通知します。したがって、正しいチェック済みステータスを取得するには:

bool bChecked = form[key].Contains("true");
于 2009-01-12T15:55:40.237 に答える
54

チェックボックスと同じ名前の非表示フィールドを入力する理由がわからない場合は、理由は次のとおりです。

ソースコードからのコメントMVCBetaSource\MVC \ src \ MvcFutures \ Mvc \ ButtonsAndLinkExtensions.cs

チェックボックスの追加をレンダリング<input type="hidden".../>します。これは、チェックされていないチェックボックスがリクエストで送信されないシナリオに対処します。非表示の入力を送信すると、リクエストが送信されたときにチェックボックスがページに存在していたことを知ることができます。

舞台裏では、コントローラーのアクションメソッドのパラメーターにバインドするためにこれを知る必要があると思います。次に、私が推測するトライステートブール値(null許容のブール値パラメーターにバインドされている)を持つことができます。私はそれを試していませんが、彼らがやったことを望んでいます。

于 2009-01-26T09:29:49.207 に答える
49

<label for="checkbox1">Checkbox 1</label>チェックボックス自体だけでなく、ラベルのテキストをクリックできるため、これも使用する必要があります。また、スタイル設定も簡単で、少なくともIEでは、ページのコントロールをタブで移動すると強調表示されます。

<%= Html.CheckBox("cbNewColors", true) %><label for="cbNewColors">New colors</label>

これは単なる「ああ、私はそれができる」ことではありません。その重要なユーザーエクスペリエンスの強化。すべてのユーザーがラベルをクリックできることを知っていなくても、多くのユーザーがそうします。

于 2009-01-26T09:19:13.643 に答える
27

これらの回答のどれも、これに組み込みの MVC 機能を使用していないことに驚いています。

これについてのブログ投稿をここに書きましたが、実際にはラベルをチェックボックスにリンクしています。EditorTemplateフォルダーを使用して、クリーンでモジュール化された方法でこれを実現しました。

EditorTemplate フォルダーに次のような新しいファイルが作成されるだけです。

@model SampleObject

@Html.CheckBoxFor(m => m.IsChecked)
@Html.HiddenFor(m => m.Id)
@Html.LabelFor(m => m.IsChecked, Model.Id)

あなたの実際のビューでは、これをループする必要はありません.1行のコードだけです:

@Html.EditorFor(x => ViewData.Model)

詳細については、私のブログ投稿をご覧ください。

于 2011-10-16T03:31:12.047 に答える
25

これが私がやってきたことです。

意見:


<input type="checkbox" name="applyChanges" />

コントローラ:


var checkBox = Request.Form["applyChanges"];

if (checkBox == "on")
{
...
}

Html.* ヘルパー メソッドは、場合によってはあまり役に立たないことがわかりました。また、単純な古い HTML で実行したほうがよいことがわかりました。これはそのうちの1つで、もう1つ頭に浮かぶのはラジオボタンです。

編集: これはプレビュー 5、明らかにバージョン間の YMMV にあります。

于 2008-10-20T21:37:58.483 に答える
10

最初の値のみを読み取ることを選択しているように見えるため、チェックボックスがチェックされている場合は「true」、非表示の値のみが含まれている場合は「false」です。これは、次のようなコードで簡単に取得できます。

model.Property = collection["ElementId"].ToLower().StartsWith("true");
于 2010-03-20T20:36:06.117 に答える
8

@Dylan Beattie 大発見!!! ありがとうございます。さらに拡張するために、この手法は View Model アプローチでも完璧に機能します。MVC は非常に優れており、ビューにバインドされた Model オブジェクトと同じ名前のプロパティに Guid の配列をバインドするほどスマートです。例:

ビューモデル:

public class SampleViewModel
{
    public IList<SampleObject> SampleObjectList { get; set; }
    public Guid[] SelectedObjectIds { get; set; }

    public class SampleObject
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
    }
}

意見:

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Sample View</h2>
<table>
    <thead> 
        <tr>
            <th>Checked</th>
            <th>Object Name</th>
        </tr>
    </thead> 
<% using (Html.BeginForm()) %>
<%{%>                    
    <tbody>
        <% foreach (var item in Model.SampleObjectList)
           { %>
            <tr>
                <td><input type="checkbox" name="SelectedObjectIds" value="<%= item.Id%>" /></td>
                <td><%= Html.Encode(item.Name)%></td>
            </tr>
        <% } %>
    </tbody>
</table>
<input type="submit" value="Submit" />
<%}%>                    

コントローラ:

    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult SampleView(Guid id)
    {
        //Object to pass any input objects to the View Model Builder 
        BuilderIO viewModelBuilderInput = new BuilderIO();

        //The View Model Builder is a conglomerate of repositories and methods used to Construct a View Model out of Business Objects
        SampleViewModel viewModel = sampleViewModelBuilder.Build(viewModelBuilderInput);

        return View("SampleView", viewModel);
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult SampleView(SampleViewModel viewModel)
    {
        // The array of Guids successfully bound to the SelectedObjectIds property of the View Model!
        return View();
    }

ビュー モデルの哲学に詳しい人なら誰でも喜ぶでしょう。これはチャンピオンのように機能します。

于 2010-06-04T15:24:48.990 に答える
6

また、各チェックボックスに別の名前を付けて、その名前を actionresults パラメータの一部にすることもできます。

例、

意見:

 <%= Html.CheckBox("Rs232CheckBox", false, new { @id = "rs232" })%>RS-232

 <%= Html.CheckBox("Rs422CheckBox", false, new { @id = "rs422" })%>RS-422

コントローラ:

public ActionResults MyAction(bool Rs232CheckBox, bool Rs422CheckBox) {
    ...
}

名前が同じであるため、ビューからの値がアクションに渡されます。

このソリューションがあなたのプロジェクトにとって理想的ではないことはわかっていますが、私はアイデアをそこに捨てたいと思いました.

于 2010-03-22T14:48:25.790 に答える
5
<input type = "checkbox" name = "checkbox1" /> <label> Check to say hi.</label>

コントローラーから:

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(FormCollection fc)
    {

         var s = fc["checkbox1"];

         if (s == "on")
         {
             string x = "Hi";
         }
    }
于 2010-06-21T19:41:28.580 に答える
4

この問題は、リリース1.0でも発生しています。Html.Checkbox()を使用すると、元のチェックボックスと同じ名前/IDで別の非表示フィールドが追加されます。そして、document.GetElemtentsByName()を使用してチェックボックス配列をロードしようとしていたので、物事がどのように混乱していたかを推測できます。それは奇妙です。

于 2010-01-18T11:23:28.397 に答える
4

この質問は MVC3 がリリースされていないときに書かれたものですが、この質問に来て MVC3 を使用している人にとっては、これを行うための「正しい」方法が必要になる場合があります。

と思いながら

Contains("true");

これは素晴らしくクリーンで、すべての MVC バージョンで動作しますが、問題は文化が考慮されていないことです (bool の場合は本当に重要であるかのように)。

少なくとも MVC3 では、bool の値を把握する「正しい」方法は、ValueProvider を使用することです。

var value = (bool)ValueProvider.GetValue("key").ConvertTo(typeof(bool));

アクセス許可を編集するときに、クライアントのサイトの 1 つでこれを行います。

var allPermissionsBase = Request.Params.AllKeys.Where(x => x.Contains("permission_")).ToList();
var allPermissions = new List<KeyValuePair<int, bool>>();

foreach (var key in allPermissionsBase)
{
     // Try to parse the key as int
     int keyAsInt;
     int.TryParse(key.Replace("permission_", ""), out keyAsInt);

     // Try to get the value as bool
     var value = (bool)ValueProvider.GetValue(key).ConvertTo(typeof(bool));
}

さて、これの美しさは、これをほぼすべての単純な型で使用できることであり、カルチャ (お金、小数などを考えてください) に基づいて正しいことさえあります。

ValueProvider は、次のようにアクションを作成するときに使用されるものです。

public ActionResult UpdatePermissions(bool permission_1, bool permission_2)

しかし、これらのリストを動的に作成して値をチェックしようとすると、コンパイル時に Id がわからないため、その場で処理する必要があります。

于 2012-06-14T23:07:43.770 に答える
4

私が収集できることから、モデルはchecked = trueかfalseかを推測したくありません。フォームを送信する前に、jQueryを使用してcheckbox要素にvalue属性を設定することでこれを回避しました。

 $('input[type="checkbox"]').each(function () {
       $(this).attr('value', $(this).is(':checked'));
 }); 

このように、チェックボックスの値を格納するためだけに非表示の要素は必要ありません。

于 2012-05-22T21:32:21.343 に答える
3

nautic20 の回答と同じように、ViewModel の string/int/enum のコレクション プロパティと同じ名前の MVC デフォルト モデル バインディング チェックボックス リストを使用するだけです。それだ。

しかし、指摘しなければならない問題が 1 つあります。各チェックボックス コンポーネントには、MVC モデル バインディングに影響する "Id" を入れないでください。

次のコードは、モデル バインディングで機能します。

 <% foreach (var item in Model.SampleObjectList)
       { %>
        <tr>
            <td><input type="checkbox" name="SelectedObjectIds" value="<%= item.Id%>" /></td>
            <td><%= Html.Encode(item.Name)%></td>
        </tr>
 <% } %>

次のコードはモデルにバインドされません (ここでの違いは、各チェックボックスに割り当てられた ID です)

<% foreach (var item in Model.SampleObjectList)
       { %>
        <tr>
            <td><input type="checkbox" name="SelectedObjectIds" id="[some unique key]" value="<%= item.Id%>" /></td>
            <td><%= Html.Encode(item.Name)%></td>
        </tr>
<% } %>
于 2014-03-11T17:05:00.417 に答える
3

最も簡単な方法はそうです...

名前と値を設定します。

<input type="checkbox" name="selectedProducts" value="@item.ProductId" />@item.Name

次に、送信時にチェックボックスの値を取得し、int 配列に保存します。次に、適切な LinQ 関数。それでおしまい..

[HttpPost]
        public ActionResult Checkbox(int[] selectedObjects)
        {
            var selected = from x in selectedObjects
                           from y in db
                           where y.ObjectId == x
                           select y;                   

            return View(selected);
        }
于 2012-01-05T16:10:31.090 に答える
2

これは、Html.CheckBox(...

Replace("true,false","true").Split(',')

4つのボックスがチェックされている、チェックされていない、チェックされていない、チェックされていると、true、false、false、false、true、falseがtrue、false、false、trueになります。私が必要としていたものだけ

于 2010-10-22T16:07:08.947 に答える
0

このようなものはどうですか?

bool isChecked = false;
if (Boolean.TryParse(Request.Form.GetValues(”chkHuman”)[0], out isChecked) == false)
    ModelState.AddModelError(”chkHuman”, “Nice try.”);
于 2010-11-11T20:49:15.830 に答える
0

チェックボックス HtmlHelper を使用する場合、ポストされたチェックボックス フォーム データを配列として操作することを好みます。理由はよくわかりませんが、他の方法が機能することはわかっていますが、コンマ区切りの文字列をできるだけ配列として扱うことを好むと思います。

したがって、「チェック済み」または真のテストを行うと、次のようになります。

//looking for [true],[false]
bool isChecked = form.GetValues(key).Contains("true"); 

誤ったチェックを行うと、次のようになります。

//looking for [false],[false] or [false]
bool isNotChecked = !form.GetValues(key).Contains("true"); 

主な違いはGetValues、これを配列として返すように使用することです。

于 2011-04-20T22:25:36.203 に答える
0

@mmacaulay を使用して、ブールにこれを思いつきました:

// MVC Work around for checkboxes.
bool active = (Request.Form["active"] == "on");

有効にチェックされている場合 = true

チェックされていない場合アクティブ = false

于 2014-02-25T23:02:14.640 に答える
0

これを行うだけです$(document).ready

$('input:hidden').each(function(el) {
    var that = $(this)[0];
    if(that.id.length < 1 ) {

        console.log(that.id);
        that.parentElement.removeChild(that);

    }
});
于 2011-08-10T15:38:26.103 に答える
0

私の解決策は次のとおりです。

<input type="checkbox"  id="IsNew-checkbox"  checked="checked" />     
<input type="hidden"  id="IsNew" name="IsNew" value="true"  />      
<script language="javascript" type="text/javascript" >     
  $('#IsNew-checkbox').click(function () {    
      if ($('#IsNew-checkbox').is(':checked')) {    
          $('#IsNew').val('true');    
      } else {    
          $('#IsNew').val('false');    
       }    
  });   
</script>  

詳細はこちら: http://www.blog.mieten.pl/2010/12/asp-net-mvc-custom-checkbox-as-solution-of-string-was-not-recognized-as-a-有効なブール値/

于 2010-12-29T10:20:55.973 に答える