2014-02-06 68 views
0

我有三個級聯下拉使用Ajax填充自己的視圖。同樣在視圖中,我調用一個迭代模型中的容器的局部視圖,並且爲每個項目調用另一個局部視圖,根據下拉列表中選定的項目顯示適當的編輯模型屬性。我構建了一個複雜的模型,其中包含下拉選項以及要編輯的屬性,並將模型的部分傳遞到顯示要編輯的屬性所需的最低級別部分。MVC 4模型沒有返回到控制器

我想在用戶通過正常的Html.BeginForm而不是通過使用Ajax單擊提交按鈕時更新數據庫。因此,我必須只包裝顯示錶單中屬性的部分,以便現有的Ajax功能不會發布到控制器。問題是,儘管我可以構建這一切,並且提交按鈕按預期連接到控制器,但模型返回到控制器null。

模型不是通過建立它們的路徑從部分回來的嗎?或者更準確地說,即使使用partials構建模型,模型是否仍然保留在頁面上?

我相信有人會建議我使用Ajax回發,但這不是我的最佳選擇。或者有人可能會問網頁上的html是什麼樣子。奇怪的是,我只能使用瀏覽器開發工具看到完整的html,它並沒有顯示在查看源代碼中。

任何想法?

把它移到它所屬的地方:
我不確定我的理解。我知道返回的模型需要匹配預期的模型,但我沒有得到上面的解釋。你說:「所以,如果你的控制器看起來像這樣:」,當然是這樣,那麼是什麼?那是錯的? 我要看看在開發工具Chrome瀏覽器,看看實際的HTML輸出,我看到這在一個案件:
<input class="text-box single-line" id="status_Comments" name="status.Comments" type="text" value="Last Install to be completed this weekend">

因此,如果「名」標籤需要尋找合適的,我認爲它。我錯了嗎?

我的日期字段是這樣的:
<input type="text" value="8/19/2014" class="datepicker hasDatepicker" id="dp1391795955619">

所以沒有「名」的標籤,但確實有一個ID。我需要添加一個名字嗎?

下面的代碼生成上述:
@foreach (Status status in Model) {
string date = status.Date.HasValue ? status.Date.Value.ToShortDateString() : string.Empty;
<tr>
<td style="width: 175px;">@Html.DisplayFor(model => status.Name)</td>
<td style="width: 75px;">@Html.DisplayDropdownColorFor(model => status.StatusValue)</td>
<td style="width: 80px;"><input type="text" value="@date" class="datepicker" /></td>
<td style="width: 80px;"><input type="text" value="" class="datepicker" /></td>
<td style="width: 375px;">@Html.EditorFor(model => status.Comments)</td>
</tr> }`
吉茲,我聽起來像一個絕望的白癡。 感謝您的幫助。

+4

這是很多的描述和...沒有代碼。你能提供這個問題的一個有效的例子嗎?模型綁定不是一個真正的黑盒子。您發佈的表單中有哪些表單元素?什麼鍵/值對發佈到服務器?他們是你期望的嗎?它們是否與你期望的模型結構相匹配? – David

+0

我希望避免發佈代碼,它相當複雜。表單元素都是文本框,沒有更復雜的字符串和日期。該模型是基於上一次選擇的每個下拉列表的選項列表,最後一個選項觸發一個db查詢,該查詢使用字符串填充模型的其餘部分。 – leemid

+2

我認爲你錯過了這一點。這不是概念上的形式代表的問題。這是POST請求中發送的實際鍵/值對的問題。那些需要映射到模型類的物理(而非概念)結構。沒有一個可以分享的例子,你是唯一可以證實這種情況的人。 – David

回答

0

比方說,你有這樣幾個類:

public class SomeClass1 
{ 
    public string Name { get; set; } 
    public SomeClass2 class2Value { get; set; } 
} 

public class SomeClass2 
{ 
    public string Description { get; set; } 
} 

而且你在Razor視圖形式:

@model SomeClass1 

@using (Html.BeginForm()) { 
    <fieldset> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.Name) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Name) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.class2Value.Description) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.class2Value.Description) 
     </div> 

     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 
} 

實際的HTML代碼將是這個樣子:

<form id="form1" action="/pageurl" method="POST"> 
    <fieldset> 
     <div class="editor-label"> 
      Name 
     </div> 
     <div class="editor-field"> 
      <input type="text" name="Name" id="Name" value="Name val 1" /> 
     </div> 

     <div class="editor-label"> 
      Description 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.class2Value.Description) 
      <input type="text" name="class2Value.Description" id="class2Value_Description" value="Desc val 2" /> 
     </div> 

     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 
</form> 

如果您注意到,表單字段的name屬性由M VC遵循模型。在嵌套對象的情況下,它使用ID中的下劃線和名稱中的句號來跟蹤後置模型中值的位置。

所以,如果您的控制器是這樣的:

[HttpPost] 
protected ActionResult Save(SomeClass1 model) 
{ 
    //Then 
    // SomeClass1.Name == "Name val 1" 
    // and 
    // SomeClass1.class2Value.Description == "Desc val 2" 
} 

這就是@大衛在評論越來越善於......無論多麼複雜的頁面,當<form>回發到服務器時,name您要返回的字段的屬性必須與控制器操作期望的模型對齊......否則您將獲得null值。

甚至可以爲後期模型創建自定義類,只要name屬性與模型保持一致,即使它與剃刀視圖頂部的@model不相同,MVC也會使用鍵/值對並填充後期模型中的數據。

UPDATE

我更新上述以反映的校正。下劃線是ID屬性中的分隔符,該句點用於NAME屬性中。

@leemid:一個HTML form只會發佈帶有name屬性的字段。當提交form時,只有name'ed輸入,選擇,textareas等將被傳回服務器。這些名稱必須與控制器預期的模型內聯。探空冗餘的緣故,該日期input場你表現出的例子中,沒有一個name attibute,如果name是一樣的id,就必須像

模型中的一個屬性public string dp1391795955619 { get; set; }

它會顯示在您的控制器操作中。您可以手動設置name,只要它以MVC的預期方式命名,以便在發佈時將其傳遞到模型中。

在我的例子,我是想突出的部分是類和屬性名之間的關係,與名稱屬性MVC寫入HTML文檔,並將其如何保持所有的東西直。在簡單的例子中,你不必考慮它。但是在你複雜的情況下,你將不得不手動管理一些命名約定,以便MVC能夠理解你想要做什麼。

+0

我不確定我的理解。我知道返回的模型需要匹配預期的模型,但我沒有得到上面的解釋。你說:「所以,如果你的控制器看起來像這樣:」,當然是這樣,那麼是什麼?那是錯的? 我必須查看開發工具的Chrome瀏覽器才能看到實際的html輸出,我在一個案例中看到: 所以如果'name'標籤需要看起來合適,我認爲它確實如此。我錯了嗎? 我的日期字段如下所示: – leemid

+0

我更新了答案。另外,請將答案文中的文字移動到您的問題中,並刪除「答案」:) – jwatts1980

+0

好吧,現在我明白了。讓我說,你的幫助確實有幫助,但並非總是如此。爲此,我深深感謝你。我花了很多時間在一個簡單的框架中嘲笑這一切,以便更容易理解並發現一些有趣的事情。您的意見填補了空白。 – leemid