私は、データアノテーションを使用して、空ではないモデルのリストに検証を追加しようとしています。私はhereとhereを含むカスタム属性のいくつかの実装を試みました。リストを強制できませんが必要です
マイビュー:
<div class="form-group">
@* Model has a list of ints, LocationIDs *@
@Html.LabelFor(model => model.LocationIDs, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<select class="select2 form-control" multiple id="LocationIDs" name="LocationIDs">
@* Adds every possible option to select box *@
@foreach (LocationModel loc in db.Locations)
{
<option value="@loc.ID">@loc.Name</option>
}
</select>
@Html.ValidationMessageFor(model => model.LocationIDs, "", new { @class = "text-danger" })
</div>
</div>
モデル:
public class ClientModel
{
public int ID { get; set; }
[Required] // Does nothing
public List<int> LocationIDs { get; set; }
}
コントローラ:(機能的に同一)の
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,LocationIDs")] ClientModel clientModel)
{
if (ModelState.IsValid)
{
db.Clients.Add(clientModel);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(clientModel);
}
一つ、私が試した属性:
[AttributeUsage(AttributeTargets.Property)]
public sealed class CannotBeEmptyAttribute : RequiredAttribute
{
public override bool IsValid(object value)
{
var list = value as IEnumerable;
return list != null && list.GetEnumerator().MoveNext();
}
}
現在、nullまたは空のリストをチェックすると、何も選択されていなくても検証が行われます。この場合、最初のオプションを含む長さ1のリストがバインドされます。
私は、コントローラが実際に長さ1のList
を送っていることを確認しました。しかし、私はこの振る舞いをどのように変更するかはわかりません。私はまだこれが下のブロック引用で記述されたものかもしれないと思います。
は私が は私の問題は this answer's editで説明することができると思いますが、私はそれを解決するかどうかはわかりません。以下
抜粋:
はまた、あなたはビューであなたのリストをバインドする方法に注意する必要があります。 たとえば、あなたがこのようなビューにリストをバインドする場合:
<input name="ListName[0]" type="text" />
<input name="ListName[1]" type="text" />
<input name="ListName[2]" type="text" />
<input name="ListName[3]" type="text" />
<input name="ListName[4]" type="text" />
をMVCモデルバインダーは常に、あなたの リスト内のすべてのString.Emptyをする5つの要素を配置します。これがViewの仕組みであれば、 の属性はReflectionを使用して ジェネリック型パラメータを引き出し、各リスト要素を デフォルト(T)などと比較するなど、少し複雑にする必要があります。
エンドユーザーが 'select'でアイテムを選択したことを検証しようとしていますか、' model.LocationIDs'にエントリがあることを検証しようとしていますか、あるいはその両方ですか? – mjwills
どちらも、私は思います。クライアント側は 'select'、サーバ側は' model.LocationIDs'となります。オートマチックの検証プロパティーを100%完全に理解しているわけではありませんが、データアノテーションによって無効な値が保存されるのを防ぐことができます(必須)。 – Sinjai
@mjwillsもっと明確にするために私の質問を編集するにはどうすればよいですか? – Sinjai