EDIT2
動作する簡単なサンプル プロジェクトを作成しました。私が気に入らないことが 1 つあります。それは、リスト自体を渡すことができないことです。毎回空白のリストを作成し、テキスト ボックスからすべての値を読み取り、これをリストに保存して、この更新されたリストを新しいビューに与える必要があります。次のラウンドも同じ。しかし、それは機能します。
基本的:
public ActionResult About() {
List<FormMetaData> formItems = GetFormItems();
return View(formItems);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult About(FormCollection form)
{
List<FormMetaData> formItems = GetFormItems();
//TryUpdateModel(formItems);
// update project members
foreach (var key in form.AllKeys) {
if (key.ToString().StartsWith("TextBox")) {
string field = (key.ToString().Replace("TextBox", ""));
if (!string.IsNullOrEmpty(form.Get(key.ToString()))) {
formItems.Find(delegate(FormMetaData t) { return t.Field == field; }).Value = form.Get(key.ToString());
}
else { }
// this.ProjectRepository.DeleteMemberFromProject(id, userId);
}
}
ModelState.AddModelError("test", "this is a test error");
if(ModelState.IsValid)
{
///
}
else
{
return View(formItems);
}
return View(formItems);
}
private List<FormMetaData> GetFormItems() {
List<FormMetaData> output = new List<FormMetaData>();
FormMetaData temp1 = new FormMetaData("TextBox",true,"temp1","displayText1");
FormMetaData temp2 = new FormMetaData("TextBox", true, "temp2", "displayText2");
output.Add(temp1);
output.Add(temp2);
return output;
}
そして、あなたの見解があります:
<% using (Html.BeginForm()) {%>
<table>
<% foreach (var item in Model) {
if (!item.isActive) {
continue;
} %>
<tr>
<td>
<%=Html.Encode(item.DisplayValue)%>
</td>
<td>
<% if (item.FieldType == "TextBox") {%>
<%=Html.TextBox("TextBox"+item.Field, item.Value)%>
<%} if (item.FieldType == "CheckBox") {%>
<%=Html.CheckBox("Value")%>
<%}%>
</td>
<td>
</td>
</tr>
<%} %>
<p>
<input type="submit" value="submit" />
</p>
<% } %>
</table>
@ http://www.bastijn.nl/zooi/dynamicSample.rarに zip ファイルをアップロードしました。
編集
この例を試してみましたが、モデルバインダーでうまくいきません。「FormCollectionフォーム」をPOST createメソッドへの入力として使用すると、テキストボックスの値が指定されたキーの下にあります。そのため、カスタム モデル バインダーを作成するか、デフォルトのモデル バインダーで動作するモデルを作成する必要があります。
もう少し詳しく言うと。この場合、テキスト ボックスは、渡されたモデルであるList内のオブジェクトのプロパティを更新しているため、問題が発生します。通常、テキストボックスはモデルでもあるオブジェクト内のプロパティを更新しており、テキストボックスに使用されるキー (自動モデルバインディング用) は、更新するプロパティの名前です。
したがって、モデル バインダーは、テキスト ボックス内の値をリスト内のアイテムにバインドしないと思います。これは、これを自動的に行う方法がわからないためです。今ここにいるのは午前 3 時 17 分なので、就寝します。質問は興味深いもので、明日には回答を終えるかもしれません。
オリジナル
<%=Html.TextBox(item.Field, null, new { tabindex = item.SortOrder })%>
値をnullに設定して毎回フォームを生成しているようです。
次のように初期化してみてください。
<%=Html.TextBox(item.Field, **item.Value**, new { tabindex = item.SortOrder })%>
コントローラーでModelState.isValidをチェックするときは、次のようにします。
if(ModelState.isValid){
//code when it works
}
else{
return View(formItems) // these should contain the just added values
}
これでうまくいくはずです。
したがって、簡単な例では、次のようになります。
public ActionResult Create()
{
List<FormMetadata> formItems = GetFormItems();
return View(formItems);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(List<FormMetadata> formItems)
{
if(ModelState.isValid)
{
MyUpdate()
save()
}
else
{
return view(formItems)
}
}
そしてあなたの見解:
<%
if (item.FieldType == "TextBox")
{%>
<%=Html.TextBox(item.Field, **item.Value**, new { tabindex = item.SortOrder })%>
<%}
if (item.FieldType == "CheckBox")
{%>
<%=Html.CheckBox(item.Field, **item.Value**, new { tabindex = item.SortOrder })%>
<%}