このカスタムモデルバインダーと通常のHTMLを使用して、かなりうまく機能...
まず、カミソリの構文で、あなたのHTMLフォーム:
@using (Html.BeginForm("Action", "Controller", FormMethod.Post)) {
<ol>
<li><input type="textbox" name="tBox" value="example of another form element" /></li>
<li><input type="checkbox" name="cBox" value="1" /> One</li>
<li><input type="checkbox" name="cBox" value="2" /> Two</li>
<li><input type="checkbox" name="cBox" value="3" /> Three</li>
<li><input type="checkbox" name="cBox" value="4" /> Four</li>
<li><input type="checkbox" name="cBox" value="5" /> Five</li>
<li><input type="submit" /></li>
</ol>
}
(FormMethod.Post
も.Get
可能性があり、重要ではありません。
:
続い)このために、適切なMVCの意味で自分のフォームの送信を表すモデルオブジェクトを持っています210
カスタムモデルのバインダークラス(これはバインディングされたモデルの内側に配置したいので、上に作成したモデルを繰り返して、どこに追加するかを示します。また、)良いことですこれは、バインダーは、私有財産のセッターを使用することができます内側に配置すると:
public class CheckboxListExampleModel {
public string TextboxValue { get; private set; }
public List<int> CheckboxValues { get; private set; }
public class Binder : DefaultModelBinder {
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
var model = new CheckboxListExampleModel();
model.TextboxValue = bindingContext.GetValueAsString("tBox");
string checkboxCsv = bindingContext.GetValueAsString("cBox");
// checkboxCsv will be a comma-separated list of the 'value' attributes
// of all the checkboxes with name "cBox" which were checked
model.CheckboxValues = checkboxCsv.SplitCsv<int>();
return model;
}
}
}
.GetValueAsString()
は、明確にするために使用される拡張メソッドである、ここにある:
public static string GetValueAsString(this ModelBindingContext context, string formValueName, bool treatWhitespaceAsNull = true) {
var providerResult = context.ValueProvider.GetValue(formValueName);
if (providerResult.IsNotNull() && !providerResult.AttemptedValue.IsNull()) {
if (treatWhitespaceAsNull && providerResult.AttemptedValue.IsNullOrWhiteSpace()) {
return null;
} else {
return providerResult.AttemptedValue.Trim();
}
}
return null;
}
.SplitCsv<T>()
はですまた拡張メソッドですが、これは一般的な十分な必要性と私はそれを読者のための練習として残してくれる十分なコードです。
そして最後に、あなたの行動は、フォーム送信処理する:
[HttpPost]
public ActionResult Action([ModelBinder(typeof(CheckboxListExampleModel.Binder))] CheckboxListExampleModel model) {
// stuff
}
アイデアは悪くないですが、これ以外の項目にフォームを使用する場合、それは動作しません。たとえば、ユーザー名/パスワード+チェックボックスのコレクションがあるとします。この方法では動作しません。/ – Erick
@エリック、もちろん動作することができます。あなたのビューモデルは、 'Username'や' Password'のような単純なプロパティと、チェックボックス情報を含むコレクションプロパティIEnumerableを含んでいます。あなたのフォームに 'Html.EditorForModel'を使用するのではなく、単純な' <%= Html.TextBoxFor(x => x.Username)%> 'と' <%= Html.PasswordFor(x => x.Password) %> 'と、同じエディタテンプレートをレンダリングする' <%= Html.EditorFor(x => x.MyCheckboxes)%> 'となります。 –
私はこれを達成するための多くの方法を読んでおり、これははるかにエレガントな解決策でした。ありがとう! – JimDaniel