2009-11-24 19 views
1

我試圖構建一個動態生成的視圖。我控制器創建action類看起來像這樣ASP.NET MVC渲染當在動態生成的視圖上驗證失敗時查看並保留值

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> 

我想表明的價值觀相同的觀點保持當有驗證錯誤。如下面的代碼是用來捕捉驗證錯誤

​​

我怎麼能顯示出與驗證錯誤觀點,同時保留已經進入了此方案的價值?

+0

你能解釋一下它變得有用的場景嗎?看起來你正在嘗試製作某種EAV系統。 – Neal 2009-12-21 20:25:21

回答

0

EDIT2

我創建了一個工作快速樣本項目。有一件事我不喜歡,那就是我無法繞過這個名單。我必須每次創建空白列表並從文本框中讀取所有值並將其保存在列表中,並將此更新列表提供給新視圖。接下來的一回事。但它的工作。

基本上是:

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

編輯

我曾嘗試這個例子,它會去w與modelBinder合作。當我使用「FormCollection窗體」作爲POST創建方法的輸入時,我的文本框的值在提供的鍵下。因此,您必須使用自定義模型聯編程序或創建一個可與默認模型聯編程序配合使用的模型。

更具體一點。它出錯了,因爲在這種情況下,您的文本框正在更新列表內的對象中的屬性,這是型號通過的對象。通常情況下,您的文本框正在更新對象中的屬性,它也是也是您的型號,用於文本框的鍵(用於自動模型綁定)是您更新的屬性的名稱。

所以我想模型聯編程序不會將文本框中的值綁定到列表中的項目,因爲它只是不知道如何自動執行此操作。現在是3點17分,所以我現在要睡覺了,這個問題很有意思,明天我可能會完成答案。

<%=Html.TextBox(item.Field, null, new { tabindex = item.SortOrder })%> 

這似乎與設置爲值每次要生成您的形式。

嘗試初始化它們是這樣的:

<%=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 })%> 
      <%} 
+0

我試過這種方法。 HttpVerbs.Post創建操作中的formItem始終在控制器中發送一個空值。 – chrisk 2009-11-25 00:38:01

+0

這可能是因爲默認的modelbinder會嘗試將文本框中的值綁定到您的密鑰(第一個值)。所以實際上它必須是這樣的: <%= Html.TextBox(「item.Value」,item.Value,new {tabindex = item.SortOrder})%> 現在它試圖綁定在文本框到您的Model.item.Value。當然,你可以按照你喜歡的方式命名。 – bastijn 2009-11-25 01:45:08

+0

編輯了這個答案,針對這個問題(正如我懷疑的那樣)。 – bastijn 2009-11-25 02:18:26

0

我會首先檢查出的NerdDinner基本上使用相同的方法。

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> 

<% } %> 

而且控制器Action方法 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; 
相關問題