2012-12-09 57 views
0

我有一個Web應用程序,我想在其中顯示測試對象的表單。不同的測試實例可以有不同的模式。我可以很好地顯示它,但它不會將表單中的所有數據填充到我的模型中。爲什麼MVC 2中的ViewModel子對象爲空?

這裏是我的模型類:

public class EnterTestData 
{ 
    public string StudyId { get; set; } 
    public Test Test { get; set; } 
} 

public sealed class Test 
{ 
    public string Identity { get; set; } 
    public string Name { get; set; } 
    public IEnumerable<TestField> Fields { get; set; } 
} 

public sealed class TestField 
{ 
    public string Identity { get; set; } 
    public string Name { get; set; } 
    public string Value { get; set; } 
    public string Type { get; set; } 
} 

這裏是我查看相關部分:

<% Html.BeginForm("PostTestData", "StudiesUserInterface"); %> 
<table> 
    <% 
     foreach (var testField in Model.Test.Fields) 
      Html.RenderPartial("UserControls/TestFieldUserControlascx", testField); 

     foreach (var category in Model.Test.Categories) 
     { 
    %> 
    <tr> 
     <td colspan="2" style="font-style: italic; text-align: center;"> 
      <%=category.Name %> 
     </td> 
    </tr> 
    <% 
      foreach (var testField in category.Fields) 
       Html.RenderPartial("UserControls/TestFieldUserControlascx", testField); 

     } 
    %> 
    <tr> 
     <td colspan="2" style="text-align: right;"> 
      <input type="submit" name="newsletter" value="Enter Result" /> 
     </td> 
    </tr> 
</table> 
<% Html.EndForm(); %> 

而對於實際的文本框的局部視圖:

<tr> 
    <td> 
     <%= Model.Name %> 
    </td> 
    <td> 
     <% 
      switch (Model.Type) 
      { 
       case "date": 
       case "text": 
       case "number": 
     %> 
     <%= Html.TextBox(Model.name, Model.Value) %> 
     <% break; 
       default: %><%= Html.Label("Unknown data type") %><% break; 
      } 
     %> 
    </td> 
</tr> 

更新控制器方法:

public ActionResult EnterTestData(string studyId, string testId) 
    { 
     var testDefinition = ServiceKitLocator.GetStudyService().GetTestDefinition(testId); 

     return View(new EnterTestData { StudyId = studyId, Test = testDefinition }); 
    } 

    public ActionResult PostTestData(EnterTestData model) 
    { 
     //I'm just putting a break point here and checking the model in the debugger for now 
     return RedirectToAction("Index"); 
    } 

問題是,Test返回到我的控制器時爲空。我如何獲得它填充?爲什麼它是空的?

+0

您是否也可以顯示您的控制器操作方法? – Sampath

+0

完成。另外,我意識到我的部分視圖中的TextBox定義不好,所以我也更新了它。 – tallseth

+0

作爲一種最佳實踐,您總是嘗試爲您的操作方法提供[HttpGet]或[HttpPost]。要了解哪個是獲取和發佈的內容非常困難。 – Sampath

回答

0

我認爲問題是Html.TextBox元素。 如果您的視圖中的模型是「測試」類型是正確的,但是在您的控制器操作中您想要綁定到類型爲「測試」屬性「EnterTestData」的類型 那麼您的TextBox應該是初始化像

Html.TextBox("Test.Name", Model.Value) 

重要的部分是name參數。模型綁定器將此名稱與您的發佈操作中模型類型的屬性相匹配,在您的情況「EnterTestData」中。

您還可以使用編輯器模板視圖。這與你的局部視圖相同。 在您的項目中,轉到Views \ Shared \並創建一個名爲EditorTemplates的文件夾(如果不存在)。 在此文件夾中創建一個局部視圖並將其命名爲模板應該用於的類/類型。在你的情況「TestField.ascx」。其實你可以複製和重命名你現有的局部視圖。 在你,你有主視圖改變兩兩件事: - 使用替代的foreach - 調用編輯模板在循環 這樣的:

for(int i = 0; i < Model.Test.Fields.Count(); i++) 
      Html.EditorFor(Model => Model.Test.Fields[i]); 

在你必須改變一件事模板視圖: - 用戶TextBoxFor而不是使用TextBox 像:

Html.TextBoxFor(Model => Model.Value) 

我經常使用這種模式。它可以很容易地綁定複雜的模型。 您可能會看看生成的HTML

+0

謝謝@ developer10214。我最終通過編寫一個自定義IModelBinder來解決這個問題,並且即將發佈該答案。但是,由於這更加明確地解決了我所問的問題,我將在明天進行測試,看看它是否有效。 – tallseth