html.checkbox(list)を使用してienumerable を使用して検証
-
28-09-2019 - |
質問
ユーザーが情報を入力し、最終的にチェックボックスを使用して1人以上の顧客を選択する必要があるページに取り組んでいます。
顧客のリストは次のとおりです IEnumerable<Customer>
それを自分のモデルに渡します。使用してチェックボックスのリストを作成するにはどうすればよいですか .CheckBoxFor()
?
そして最後に、少なくとも1つのチェックボックスが選択されているかどうかを検証できるようにしたいと思います。
リクエストは、ユーザーが入力した情報を保持するオブジェクトです。
<% foreach (var customer in Model.Request.Customers) { %>
<%= Html.CheckBoxFor(/* customer */) %>
<% } %>
誰かが私を正しい方向に向けることができますか?それとも私はこれについてすべて間違っていますか?
解決
カスタムHTML拡張機能クラスを作成し、以下のようにチェックボックスフォーメソッドにオーバーロードできます。このメソッドは、メタデータを評価して、それに渡された値に評価されます(米国州のように)。 Controlleractionのフォームコレクションからチェックボックス値を取得できます。
public ActionResult Edit(FormCollection formCollection)
{
// Get the value(s)
string checkBox = formCollection["State"];
// perform validation
....
}
例は、keyvaluepairジェネリックリストを想定しています
<% foreach (var element in UnitedStatesDictionary())
{ %>
<%= Html.CheckBoxFor(model => model.State, null, element.Key) %><%= element.Value %><br />
<% } %>
htmlextensions.cs
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Routing;
public static class HtmlExtensions
{
/// <summary>
/// Checks the box for.
/// </summary>
/// <typeparam name="TModel">The type of the model.</typeparam>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <param name="html">The HTML.</param>
/// <param name="expression">The expression.</param>
/// <returns>Checkbox</returns>
public static MvcHtmlString CheckBoxFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
{
return CheckBoxFor(html, expression, new RouteDirection());
}
/// <summary>
/// Checks the box for.
/// </summary>
/// <typeparam name="TModel">The type of the model.</typeparam>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <param name="html">The HTML.</param>
/// <param name="expression">The expression.</param>
/// <param name="htmlAttributes">The HTML attributes.</param>
/// <returns>Checkbox</returns>
public static MvcHtmlString CheckBoxFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes)
{
return CheckBoxFor(html, expression, htmlAttributes, "");
}
/// <summary>
/// Checks the box for.
/// </summary>
/// <typeparam name="TModel">The type of the model.</typeparam>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <param name="html">The HTML.</param>
/// <param name="expression">The expression.</param>
/// <param name="htmlAttributes">The HTML attributes.</param>
/// <param name="checkedValue">The checked value.</param>
/// <returns>Checkbox</returns>
public static MvcHtmlString CheckBoxFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes, string checkedValue)
{
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
TagBuilder tag = new TagBuilder("input");
tag.Attributes.Add("type", "checkbox");
tag.Attributes.Add("name", metadata.PropertyName);
if (!string.IsNullOrEmpty(checkedValue))
{
tag.Attributes.Add("value", checkedValue);
}
else
{
tag.Attributes.Add("value", metadata.Model.ToString());
}
if (htmlAttributes != null)
{
tag.MergeAttributes(new RouteValueDictionary(htmlAttributes));
}
if (metadata.Model.ToString() == checkedValue)
{
tag.Attributes.Add("checked", "checked");
}
return MvcHtmlString.Create(tag.ToString(TagRenderMode.SelfClosing));
}
}
私がそれにいる間、これがコードを完成させるための米国の私のリストです:
/// <summary>
/// United States dictionary.
/// </summary>
/// <returns>List of United States</returns>
public static List<KeyValuePair<string, string>> UnitedStatesDictionary()
{
var arrList = new List<KeyValuePair<string, string>>();
arrList.Add(new KeyValuePair<string, string>("AL", "Alabama"));
arrList.Add(new KeyValuePair<string, string>("AK", "Alaska"));
arrList.Add(new KeyValuePair<string, string>("AZ", "Arizona" ));
arrList.Add(new KeyValuePair<string, string>("AR", "Arkansas" ));
arrList.Add(new KeyValuePair<string, string>("CA", "California" ));
arrList.Add(new KeyValuePair<string, string>("CO", "Colorado" ));
arrList.Add(new KeyValuePair<string, string>("CT", "Connecticut" ));
arrList.Add(new KeyValuePair<string, string>("DE", "Delaware" ));
arrList.Add(new KeyValuePair<string, string>("DC", "District Of Columbia" ));
arrList.Add(new KeyValuePair<string, string>("FL", "Florida" ));
arrList.Add(new KeyValuePair<string, string>("GA", "Georgia" ));
arrList.Add(new KeyValuePair<string, string>("HI", "Hawaii" ));
arrList.Add(new KeyValuePair<string, string>("ID", "Idaho" ));
arrList.Add(new KeyValuePair<string, string>("IL", "Illinois" ));
arrList.Add(new KeyValuePair<string, string>("IN", "Indiana" ));
arrList.Add(new KeyValuePair<string, string>("IA", "Iowa" ));
arrList.Add(new KeyValuePair<string, string>("KS", "Kansas" ));
arrList.Add(new KeyValuePair<string, string>("KY", "Kentucky" ));
arrList.Add(new KeyValuePair<string, string>("LA", "Louisiana" ));
arrList.Add(new KeyValuePair<string, string>("ME", "Maine" ));
arrList.Add(new KeyValuePair<string, string>("MD", "Maryland" ));
arrList.Add(new KeyValuePair<string, string>("MA", "Massachusetts" ));
arrList.Add(new KeyValuePair<string, string>("MI", "Michigan" ));
arrList.Add(new KeyValuePair<string, string>("MN", "Minnesota" ));
arrList.Add(new KeyValuePair<string, string>("MS", "Mississippi" ));
arrList.Add(new KeyValuePair<string, string>("MO", "Missouri" ));
arrList.Add(new KeyValuePair<string, string>("MT", "Montana" ));
arrList.Add(new KeyValuePair<string, string>("NE", "Nebraska" ));
arrList.Add(new KeyValuePair<string, string>("NV", "Nevada" ));
arrList.Add(new KeyValuePair<string, string>("NH", "New Hampshire" ));
arrList.Add(new KeyValuePair<string, string>("NJ", "New Jersey" ));
arrList.Add(new KeyValuePair<string, string>("NM", "New Mexico" ));
arrList.Add(new KeyValuePair<string, string>("NY", "New York" ));
arrList.Add(new KeyValuePair<string, string>("NC", "North Carolina" ));
arrList.Add(new KeyValuePair<string, string>("ND", "North Dakota" ));
arrList.Add(new KeyValuePair<string, string>("OH", "Ohio" ));
arrList.Add(new KeyValuePair<string, string>("OK", "Oklahoma" ));
arrList.Add(new KeyValuePair<string, string>("OR", "Oregon" ));
arrList.Add(new KeyValuePair<string, string>("PA", "Pennsylvania" ));
arrList.Add(new KeyValuePair<string, string>("RI", "Rhode Island" ));
arrList.Add(new KeyValuePair<string, string>("SC", "South Carolina" ));
arrList.Add(new KeyValuePair<string, string>("SD", "South Dakota" ));
arrList.Add(new KeyValuePair<string, string>("TN", "Tennessee" ));
arrList.Add(new KeyValuePair<string, string>("TX", "Texas" ));
arrList.Add(new KeyValuePair<string, string>("UT", "Utah" ));
arrList.Add(new KeyValuePair<string, string>("VT", "Vermont" ));
arrList.Add(new KeyValuePair<string, string>("VA", "Virginia" ));
arrList.Add(new KeyValuePair<string, string>("WA", "Washington" ));
arrList.Add(new KeyValuePair<string, string>("WV", "West Virginia" ));
arrList.Add(new KeyValuePair<string, string>("WI", "Wisconsin" ));
arrList.Add(new KeyValuePair<string, string>("WY", "Wyoming" ));
return arrList;
}
他のヒント
html.checkboxfor()拡張メソッドは次のように設計されています 編集 タイプブールのモデルの特性。 Ienumerableコレクションからいくつかのオブジェクトを選択するために使用します。それは間違っています。
正しい方法:
ビューで
<form action="/Customer/Process">
<% foreach (var customer in Model.Request.Customers)
{ %>
<input type="checkbox" name="selectedId" value="<%= customer.id %>" />
<%= customer.name %>
<br/>
<% } %>
<input type="submit"/>
</form>
コントローラーで
public string Process(IEnumerable<Guid> selectedId)
{
if (selectedId == null)
{
ModelState.AddModelError("selectedId", "Have to select at least one customer!");
return View();
}
// do something with customers' ids
}
そのためにヘルパークラスを使用しました。本当に簡単です。ヘルパークラスを使用すると、セレクトリストを使用して、ドロップダウンのために行うように、ヘルパーに配置できます。
フォルダー「ヘルパー」には、CheckBoxList.csがあります
using System;
using System.Web.Mvc;
using System.Collections.Generic;
using System.Text;
using System.Linq;
namespace MVC2_NASTEST.Helpers {
public static class CheckBoxListHelper {
public static string CheckBoxList(this HtmlHelper helper, string name, IDictionary<string, string> items) {
return CheckBoxList(helper, name, items, null, null);
}
public static string CheckBoxList(this HtmlHelper helper, string name, IDictionary<string, string> items, IDictionary<string, object> checkboxHtmlAttributes) {
return CheckBoxList(helper, name, items, null, checkboxHtmlAttributes);
}
public static string CheckBoxList(this HtmlHelper helper, string name, IDictionary<string, string> items, IEnumerable<string> selectedValues) {
return CheckBoxList(helper, name, items, selectedValues, null);
}
public static string CheckBoxList(this HtmlHelper helper, string name, IDictionary<string, string> items, IEnumerable<string> selectedValues, IDictionary<string, object> checkboxHtmlAttributes) {
var selectListItems = from i in items
select new SelectListItem {
Text = i.Key,
Value = i.Value,
Selected = (selectedValues != null && selectedValues.Contains(i.Value))
};
return CheckBoxList(helper, name, selectListItems, checkboxHtmlAttributes);
}
public static string CheckBoxList(this HtmlHelper helper, string name, IEnumerable<SelectListItem> items) {
return CheckBoxList(helper, name, items, null);
}
public static string CheckBoxList(this HtmlHelper helper, string name, IEnumerable<SelectListItem> items, IDictionary<string, object> checkboxHtmlAttributes) {
var output = new StringBuilder();
foreach (var item in items) {
output.Append("<div class=\"fields\"><label>");
var checkboxList = new TagBuilder("input");
checkboxList.MergeAttribute("type", "checkbox");
checkboxList.MergeAttribute("name", name);
checkboxList.MergeAttribute("value", item.Value);
// Check to see if it's checked
if (item.Selected)
checkboxList.MergeAttribute("checked", "checked");
// Add any attributes
if (checkboxHtmlAttributes != null)
checkboxList.MergeAttributes(checkboxHtmlAttributes);
checkboxList.SetInnerText(item.Text);
output.Append(checkboxList.ToString(TagRenderMode.SelfClosing));
output.Append(" " + item.Text + "</label></div>");
}
return output.ToString();
}
}
}
私のコントローラーのコード:
public static List<SelectListItem> lesgeverList() {
return lesgeverList(-1);
}
public static List<SelectListItem> lesgeverList(int selectedID) {
return lesgeverList(new int[] { selectedID });
}
public static List<SelectListItem> lesgeverList(int[] lg) {
NASDataContext _db = new NASDataContext();
var lesg = (from l in _db.Lesgevers
where l.LG_Naam != "leeg"
orderby l.LG_Naam, l.LG_Vnaam
select l).ToSelectList(m => m.LG_Naam + " " + m.LG_Vnaam, m => m.LG_ID.ToString(), m => lg.Contains(m.LG_ID));
return lesg.ToList();
}
//
// GET: /Projectleiders/Create
public ActionResult Create(int projID) {
ViewData["projNaam"] = getProject(projID).Proj_Kortenaam;
int[] keys = (from p in _db.ProjectleiderProjectens
where p.Proj_ID == projID
from l in _db.Lesgevers
where p.LG_ID == l.LG_ID
select l.LG_ID).ToArray();
ViewData["projleiders"] = MvcApplication.lesgeverList(keys);
return toegankelijk(projID, null);
}
//
// POST: /Projectleiders/Create
[HttpPost]
public ActionResult Create(FormCollection collection, int projID) {
if (collection["lesgeverlist"] != null) {
string[] lgevers = collection["lesgeverlist"].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
List<ProjectleiderProjecten> lst = new List<ProjectleiderProjecten>();
foreach (string s in lgevers) {
ProjectleiderProjecten prl = new ProjectleiderProjecten();
prl.LG_ID = int.Parse(s);
prl.Proj_ID = projID;
int count = (from m in _db.ProjectleiderProjectens
where m.LG_ID == prl.LG_ID && m.Proj_ID == prl.Proj_ID
select m).Count();
if (count <= 0) {
//deze bestaat nog niet
lst.Add(prl);
}
}
//var test = _db.ProjectleiderProjectens.Where(p => p.Proj_ID == projID && !lgevers.Contains(p.LG_ID.ToString())).ToList();
_db.ProjectleiderProjectens.DeleteAllOnSubmit(_db.ProjectleiderProjectens.Where(p => p.Proj_ID == projID && !lgevers.Contains(p.LG_ID.ToString())));
_db.ProjectleiderProjectens.InsertAllOnSubmit(lst);
_db.SubmitChanges();
return RedirectToAction("Index");
} else {
ModelState.AddModelError("lesgeverlist", "Je hebt geen lesgevers geselecteerd");
ViewData["projleiders"] = MvcApplication.lesgeverList();
ViewData["projNaam"] = getProject(projID).Proj_Kortenaam;
return View();
}
}
私は誰もが持つべきものであるToselectlist拡張機能を使用しています。
public static class VSKOExtensions {
public static IList<SelectListItem> ToSelectList<T>(this IEnumerable<T> itemsToMap, Func<T, string> textProperty, Func<T, string> valueProperty, Predicate<T> isSelected) {
var result = new List<SelectListItem>();
foreach (var item in itemsToMap) {
result.Add(new SelectListItem {
Value = valueProperty(item),
Text = textProperty(item),
Selected = isSelected(item)
});
}
return result;
}
}
私の作成ビューのコード(同時に編集ビューでもあります)は非常に簡単です
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MVC2_NASTEST.Models.ProjectleiderProjecten>" %>
<%@ Import Namespace="MVC2_NASTEST.Helpers" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Create
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Koppel projectleider voor
<%= ViewData["projNaam"].ToString() %></h2>
<% using (Html.BeginForm()) {%>
<%= Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%= Html.Label("Lesgevers")%>
</div>
<div class="editor-field">
<%= Html.CheckBoxList("Lesgeverlist", ViewData["projleiders"] as List<SelectListItem>)%>
<%= Html.ValidationMessage("Lesgeverlist")%>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
<div>
<%= Html.ActionLink("Back to List", "Index") %>
</div>
</asp:Content>
使い方:
すでに選択したユーザーのDBから値を取得し、IDを取得して、MVCApplication.Lesgeverlist(Keys)メソッドに渡します。
次に、SelectListを取り戻し、ViewDataに入れてください。選択した人は、開いたときに私の見解で選択されます。次に、いくつかのボックスを変更して保存すると、コレクションがnullでないかどうかを確認します(何かが選択されている)、戻ってきた変数を分割します。私は彼らを介して、彼らをintsに解析し、解析されたIDを使用してDBからユーザーを取得します。カウントで、_db.projectleiderProjeansと呼ばれる「リンクされた」テーブルに存在するかどうかを確認します
すべてが追加されたら、LINQステートメントを使用してすべての「選択されていない」ものを1回で削除します
_db.ProjectleiderProjectens.DeleteAllOnSubmit(_db.ProjectleiderProjectens.Where(p => p.Proj_ID == projID && !lgevers.Contains(p.LG_ID.ToString())));
これはかなり読みやすいと思います。すべてのオブジェクトを削除し、すべてのオブジェクトをIDを取得し、idの文字列[]にないオブジェクトを確認します
それはかなりうまく機能します私は言わなければなりません。さらに質問がある場合は、聞いてください。
クライアント側でjQuery検証を使用してから、サーバー側で自分自身を再確認するだけで、フォームコレクションに値が入力されていることを確認してください。
あなたのループには何の問題もありません。