1

動的に生成されたビューを構築しようとしています。Createアクションのコントローラークラスは次のようになります

 public ActionResult Create()
 {
        List<FormMetadata> formItems = GetFormItems();

        return View(formItems);
 }

これまでのビューは次のようなものです

<% 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(item.Field, null, new { tabindex = item.SortOrder })%>
            <%}
                if (item.FieldType == "CheckBox")
                {%>
            <%=Html.CheckBox(item.Field, false, new { tabindex = item.SortOrder })%>
            <%}

            %>
        </td>
        <td>
        </td>
    </tr>
    <%} %>
</table>

検証エラーが発生した場合に値が保持された同じビューを表示したい。次のようなコードは、検証エラーをキャッチするために使用されます

 if (string.IsNullOrEmpty(collection[item.ToString()]))
 {
         ModelState.AddModelError(key, "Required.");
 }

このシナリオで入力された値を保持しながら、検証エラーのあるビューを表示するにはどうすればよいですか?

4

3 に答える 3

0

現在、次のアプローチを使用していますが、現時点ではテキストボックスのみを使用しています

ビューには

<%
for (int i = 0; i < Model.Count; i++)
{
    var name = "formItems[" + i + "].Field";


    var htmlAttributes = new Dictionary<string, object>
                             {
                                 {"tabindex", Model[i].SortOrder},
                                 {"class", Model[i].ClientSideValidation}
                             };


%>
    <div> <%=Html.Encode(Model[i].DisplayValue)%> 
    <%=Html.TextBox(name, Model[i].DefaultValue, htmlAttributes)%> 
    <%= Html.ValidationMessage(Model[i].Field) %>
    </div>

<% } %>

そして、コントローラーのアクションメソッドGET

public ActionResult Create()
{
    List<FormMetadata> formItems = GetFormItems();

    HttpContext.Cache[FormCacheKey] = formItems;

    return View(formItems);
}

POST(コードの一部)

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create(List<FormMetadata> formItems)
    {
        var formDefinition = new List<FormMetadata>();

        try
        {
            if (HttpContext.Cache[FormCacheKey] != null)
            {
                formDefinition = HttpContext.Cache[FormCacheKey] as List<FormMetadata>;
            }
            else
            {
                formDefinition = GetFormItems();
                HttpContext.Cache[FormCacheKey] = formItems;
            }

            var formValues = new Dictionary<string, string>();

            for (int i = 0; i < formDefinition.Count; i++)
            {
                var key = formDefinition[i].Field;

                var value = formItems[i].Field ?? string.Empty;
于 2009-11-26T20:25:57.867 に答える
0

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 })%>
            <%}
于 2009-11-24T22:32:18.080 に答える
0

最初に NerdDinner をチェックアウトし、基本的に同じアプローチを使用します。

于 2009-11-24T23:58:24.487 に答える