ASP.NET MVC 4でのチェックボックス値の取得


122

ASP.NET MVC 4アプリに取り組んでいます。このアプリには基本的なフォームがあります。私のフォームのモデルは次のようになります。

public class MyModel
{
    public string Name { get; set; }
    public bool Remember { get; set; }
}

私のフォームには、次のHTMLがあります。

<input id="Name" name="Name" type="text" value="@Model.Name" />
<input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />
<label for="Remember">&nbsp;Remember Me?</label>

フォームを投稿すると、モデルの記憶値が常にfalseになります。ただし、モデルのNameプロパティには値があります。以下にブレークポイントを設定して、これをテストしました。

[HttpPost]
public ActionResult MyAction(MyModel model)
{
  Console.WriteLine(model.Remember.ToString());
}

分かりません。チェックボックスの値が設定されないのはなぜですか?


適切な値で投稿されますか?フィドラーを使用してそれを確認できますか?また、チェックボックスの値がブール値に変換されるかどうか、またはどのように変換されるかわかりません。
shahkalpesh 2013

これは「オン」または「オフ」としてフォームに投稿されます。これは明らかに拘束力がない。これを避けるために私は愚かな列挙型を作りました。
Yablargo、2015年

@Yablargo、列挙型は必要ありません。value = "true"をinputタグに追加するだけです。以下に示すように、value = "false"の隠しファイルを使用します。
同所性の集計、

回答:


213
@Html.EditorFor(x => x.Remember)

生成されます:

<input id="Remember" type="checkbox" value="true" name="Remember" />
<input type="hidden" value="false" name="Remember" />

どのように機能しますか:

  • 場合checkbox遺骨がオフに、フォームの提出のみhidden値(偽)
  • チェックすると、フォームは2つのフィールド(falseとtrue)を送信し、MVC trueはモデルのboolプロパティに設定 します

<input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />

オンにすると、常にデフォルト値が送信されます。


7
こんにちは。この動作により、[true、false]を単一のブール値に変換する方法を理解できないため、モデルの検証が失敗します。これをどのように回避しますか?
オビ

@ObiOnuorahどんな構造を使用していますか?ヘルパーまたはハードコードされたhtmlマークアップ?
webdeveloper 2013年

5
Html.EditorForまたはHtml.CheckBoxForはどちらも同じ結果になります
Obi

3
formCollectionが使用される場合、結果としてチェックボックスに返される文字列は「true、false」です。これをどのように解析しますか?Replace()が唯一のオプションですか?
Jo Smo、2015

7
独自のチェックボックスを手動で追加する場合、重要な部分はその"true"に設定する必要があります。それ以外の場合、フォームから返されるデフォルト値"on"になり、 "on"はブール値にバインドできませんtrue / falseが必要です。(値 "on"がフィールドに対して無効であるという検証エラーが表示される場合があります。)
Greg

69

Model.Nameを使用して値を設定しているため。空のビューモデルをビューに渡していると思います。

したがって、Rememberの値はfalseであり、checkbox要素の値をfalseに設定します。つまり、チェックボックスを選択すると、フォームに「false」という値が投稿されます。選択しない場合は投稿されないため、モデルのデフォルトはfalseです。これが、両方のケースで誤った値が表示される理由です。

値は、選択ボックスをオンにしたときにのみ渡されます。MVCでチェックボックスを使用するには

@Html.CheckBoxFor(x => x.Remember)

または、モデルをビューにバインドしたくない場合。

@Html.CheckBox("Remember")

Mvcは、非表示フィールドを使用して、値が選択されていないときに値を永続化する魔法をかけます。

編集、あなたが本当にそうすることに嫌悪感があり、自分で要素を生成したいなら、あなたはそうすることができます。

<input id="Remember" name="Remember" type="checkbox" value="true" @(Model.Remember ? "checked=\"checked\"" : "") />

2
@Html.CheckboxForコードは、実際にする必要があります@Html.CheckBoxFor
fujiiface

簡単なの@(Model.Remember ? "checked=\"checked\"" : "")は、ラジオボタンでどのように使用するかです。またはそれは不可能です
Izzy

このオプションを使用すると、HTMLを直接操作するだけで、ラジオボタンはだけtype="radio"です。HTMLで選択するものを選択することは、上記と同じchecked="checked"です。違い<input />は、同じ名前の要素が複数あることです。それらのうちどれを追加のHTMLに適用するかを決定する必要があります。
Dan Saltmer

@Html.CheckBoxFor(x => x.Remember)これは私のために働きました
JustLearning

15

これだけを使う

$("input[type=checkbox]").change(function () {
    if ($(this).prop("checked")) {
        $(this).val(true);
    } else {
        $(this).val(false);
    }
});

または:$(this).val($(this).is(":checked"));
ノーマン

5

の代わりに

 <input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />

使用する:

 @Html.EditorFor(x => x.Remember)

これにより、Remember専用のチェックボックスが表示されます


4

さて、チェックボックスは少し変です。Htmlヘルパーを使用すると、マークアップに2つのチェックボックス入力が生成され、チェックされている場合、両方がIEnumerableの名前と値のペアとして渡されます。

マークアップでチェックされていない場合、falseの値を持つ非表示の入力のみに渡されます。

したがって、たとえば、マークアップでは次のようになります。

      @Html.CheckBox("Chbxs") 

そして、コントローラのアクションで(名前がコントローラのチェックボックスのパラメータ名と一致することを確認してください):

      public ActionResult Index(string param1, string param2,
      string param3, IEnumerable<bool> Chbxs)

次に、コントローラで次のようなことができます:

      if (Chbxs != null && Chbxs.Count() == 2)
        {
            checkBoxOnMarkup = true;
        }
        else
        {
            checkBoxOnMarkup = false;
        }

これはエレガントな解決策ではないことを知っています。ここの誰かがいくつかの指針を与えることを願っています。


3

フォームのチェックボックスから返された値をブール値のプロパティに変換するために、カスタムModelBinderのビルドコンバーターでValueProviderResultを使用しました。

ValueProviderResult cbValue = bindingContext.ValueProvider.GetValue("CheckBoxName");
bool value = (bool)cbValue.ConvertTo(typeof(bool));

3

モデルではなくFormCollectionを使用する場合、割り当ては次のように簡単です。

MyModel.Remember = fields["Remember"] != "false";

2

私は同様の問題に遭遇し、チェックボックス、hiddenfor、および次のような小さなJQueryを使用してチェックボックスの値を取得することができました。

@Html.CheckBox("isPreferred", Model.IsPreferred)
@Html.HiddenFor(m => m.IsPreferred)

<script>

    $("#isPreferred").change(function () {

        $("#IsPreferred").val($("#isPreferred").val());

    })

</script>

2

これは大きな苦痛であり、もっと簡単なはずだと感じています。これが私のセットアップとソリューションです。

次のHTMLヘルパーを使用しています。

@Html.CheckBoxFor(model => model.ActiveFlag)

次に、コントローラーでフォームのコレクションをチェックし、それに応じて処理します。

bool activeFlag = collection["ActiveFlag"] == "false" ? false : true;
[modelObject].ActiveFlag = activeFlag;

同意し、user.IsActive = fc["IsActive"] != "false";文字列の比較を行うことにまだ汚れているので、これをさらに短くしました。
WildJoe

1

私はこれに遭遇しました(それがオン/オフにバインドされないなんて信じられません!)

いずれかの方法!

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

「オン」または「オフ」の値をポストします。

このWONTはブール値にバインドしますが、このばかげた回避策を実行できます!

 public class MyViewModel
 {
     /// <summary>
     /// This is a really dumb hack, because the form post sends "on" / "off"
     /// </summary>                    
     public enum Checkbox
     {
        on = 1,
        off = 0
     }
     public string Name { get; set; }
     public Checkbox Checked { get; set; }
}

1
@Html.EditorFor(x => x.ShowComment)


$(function () {
        // set default value to control on document ready instead of 'on'/'off' 
        $("input[type='checkbox'][name='ShowComment']").val(@Model.ShowComment.ToString().ToLower());
    });

    $("#ShowComment").change(function() {
        // this block sets value to checkbox control for "true" / "false"

        var chkVal = $("input[type='checkbox'][name='ShowComment']").val();
        if (chkVal == 'false') $("input[type='checkbox'][name='ShowComment']").val(true);
        else $("input[type='checkbox'][name='ShowComment']").val(false);

    });

3
Surendran様、Stack Overflowへようこそ。コードを含める場合は、読みやすいようにフォーマットしてください。しかし、さらに重要なことに、インクルードされたコードがOPの質問に対処する理由を説明することが重要です。
Alex A.

1

モデルを使用するMVCの場合。モデル:

public class UserInfo
{
    public string UserID { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public bool RememberMe { get; set; }
}

HTML:

<input type="checkbox" value="true" id="checkbox1" name="RememberMe" checked="@Model.RememberMe"/>
<label for="checkbox1"></label>

[HttpPost]関数では、そのプロパティを取得できます。

[HttpPost]
public ActionResult Login(UserInfo user)
{
   //...
   return View(user);
}

1

(何らかの理由で)プレーンHTMLを使用し、組み込みのHtmlHelper拡張機能を使用したくない場合は、この方法で行うことができます。

の代わりに

<input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />

使ってみる

<input id="Remember" name="Remember" type="checkbox" value="true" @(Model.Remember ? "checked" : "") />

HTMLのチェックボックス入力は、チェックされると値を送信し、チェックされない場合は何も送信しないように機能します(これにより、ASP.NET MVCはデフォルトの値にフォールバックしますフィールド、false)。また、HTMLのチェックボックスの値は、true / falseだけでなく、モデルの文字列フィールドのチェックボックスを使用することもできます。

組み込みのを使用する場合Html.RenderCheckbox、実際にはチェックボックスと非表示フィールドの2つの入力が出力されるため、チェックボックスがオフの場合(何もない場合)にfalse値が送信されます。これにより、次のような予期しない状況が発生する可能性があります。


0

同じ名前の複数のチェックボックスの場合...不要なfalseを削除するコード:

List<string> d_taxe1 = new List<string>(Request.Form.GetValues("taxe1"));
d_taxe1 = form_checkbox.RemoveExtraFalseFromCheckbox(d_taxe1);

関数

public class form_checkbox
{

    public static List<string> RemoveExtraFalseFromCheckbox(List<string> val)
    {
        List<string> d_taxe1_list = new List<string>(val);

        int y = 0;

        foreach (string cbox in val)
        {

            if (val[y] == "false")
            {
                if (y > 0)
                {
                    if (val[y - 1] == "true")
                    {
                        d_taxe1_list[y] = "remove";
                    }
                }

            }

            y++;
        }

        val = new List<string>(d_taxe1_list);

        foreach (var del in d_taxe1_list)
            if (del == "remove") val.Remove(del);

        return val;

    }      



}

これを使って :

int x = 0;
foreach (var detail in d_prix){
factured.taxe1 = (d_taxe1[x] == "true") ? true : false;
x++;
}

0
public ActionResult Index(string username, string password, string rememberMe)
{
   if (!string.IsNullOrEmpty(username))
   {
      bool remember = bool.Parse(rememberMe);
      //...
   }
   return View();
}

0

このように覚えておいてください

public class MyModel
{
    public string Name { get; set; }
    public bool? Remember { get; set; }
}

コントローラでnull可能なブール値を使用し、このようにnullでfalseにフォールバックします

[HttpPost]
public ActionResult MyAction(MyModel model)
{
    model.Remember = model.Remember ?? false;
    Console.WriteLine(model.Remember.ToString());
}

0

私の場合、getメソッドでモデルプロパティ「Remember」を設定していませんでした。コントローラのロジックを確認してください。あなたは同じことをしているかもしれません。これがお役に立てば幸いです。


0

私は他の回答を読みましたが、うまく機能していませんでした。そこで、私が最終的に解決したのがこれです。

私のフォームはを使用しHtml.EditorFor(e => e.Property)てチェックボックスを生成FormCollectionし、コントローラーでこれを使用して、コントローラーにの文字列値を渡します'true,false'

結果を処理するときは、ループを使用して結果を循環させInfoPropertyます。また、インスタンスを使用して、フォームから評価される現在のモデル値を表します。

そのため、代わりに、返される文字列が単語で始まるかどうかを確認し'true'、ブール変数をに設定して、trueそれを戻りモデルに渡します。

if (KeyName.EndsWith("OnOff"))
{
    // set on/off flags value to the model instance
    bool keyTrueFalse = false;
    if(values[KeyName].StartsWith("true"))
    {
        keyTrueFalse = true;
    }
    infoProperty.SetValue(processedInfo, keyTrueFalse);
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.