2011-03-25 17 views
11

我有1個文本框使用TextBoxFor包含數據。Razor MVC模型正在丟失數據保存操作

我有一個模型和一些其他基本數據的標識,但作爲標籤直接顯示在視圖中。

當我提交表單時,只有textbox字段有模型數據,其他所有數據都是空的,包括Id。這意味着它不會保存到數據庫中。

什麼會導致所有的字段爲空的文本框?

+0

請發佈您的代碼.. – 2011-03-25 17:14:05

+1

請發佈說明問題的*最小*(即不是您的整個應用程序)代碼。包括您的視圖代碼以及相關的操作方法。 – marcind 2011-03-25 17:15:20

+0

@Bugai,我知道在沒有代碼的情況下診斷問題非常困難,但是當您在代碼中有大量代碼時,它確實非常困難的發佈代碼:1)視圖,2)控制器,3)模型,這些都包含上下文與問題無關。 – jaffa 2011-03-25 17:22:09

回答

16

這是路網工程,只有形成元素與表單提交和標籤不構成元素。

這裏什麼普遍的情況是,您:

  1. 渲染包含ID和文本框沿隱藏字段(Html.Hidden/Html.HiddenFor
  2. 接受你的控制器動作的變化(如參數或對象)
  3. 水合物/數據庫
  4. 憑身份證從你的資料庫所代表的對象的實例應用更改到水合實例
  5. 驗證對象的狀態,並更新你的資料庫/數據庫(或任何你打算用它做)

由於發佈數據類往往是由於其缺少的屬性(那些標記爲[Required]「無效」例如),它非常常見的做一個只有屬性被改變的新類(稱爲「命令模型」)。這個類可以有它自己的驗證屬性,因此不會影響你的表單驗證。

+0

非常好,謝謝你的清晰和簡潔的迴應。這使得它更清晰,我的工作有很多工作要從我的大腦中去除網絡心態! – jaffa 2011-03-26 22:16:47

6

只有輸入回送到服務器。如果您希望基於頁面上的數據填充模型,則它們必須位於輸入中(或部分網址)。標籤元素中的數據不會通過表單發佈到服務器(這是標準的HTML表單行爲)。通常,您會使用隱藏字段來回發不可編輯的模型數據,或者只是引用模型ID並從數據庫重新填充,以更新可編輯屬性(如下所示)。

例子:

@(using Html.BeginForm(new { id = Model.ID })) 
{ 
     <p> 
      <label>Fixed Property:</label> 
      @Model.SomeFixedProperty 
     </p> 
     <p> 
      @Html.LabelFor(m => m.EditableProperty) 
      @Html.TextBoxFor(m => m.EditableProperty) 
     </p> 
} 

控制器

[HttpPost] 
public ActionResult Foo(int id, string editableProperty) 
{ 
    var model = repo.GetById(id); 
    model.EditableProperty = editableProperty; 
    repo.Save(); 
    return View(model); 
} 
+0

好的,但是如果你有一個顯示10個標籤的整個表單和1個用於編輯的標籤。我應該如何將這些數據返回到模型中,而不會重置所有內容?聽起來像這是ViewState會解決的一個主要問題? – jaffa 2011-03-25 17:24:28

+1

@Jon - (1)隱藏字段與標籤一起用於模型中需要重新填充的每個事物,(2)使用TempData來保存先前請求中的數據,或者(3)包含足夠的信息來重新構造所需的數據。 ViewState實際上做(1),雖然數據是加密的。如果你願意,你可以複製這個功能,但我不會推薦它。根據你的說法,我可能會選擇(3)並在模板中包含模型ID。讓您的控制器操作將id和更新的數據作爲參數。從數據庫中檢索模型並只需要修改wnat。 – tvanfosson 2011-03-25 17:27:44

+0

@Jon - 請仔細查看會話狀態並瞭解它如何在依賴TempData之前進行擴展,因爲這是'TempData'包裝的內容。 – 2011-03-25 22:40:14

0

儘管我同意@RichardSzalay,另一種方法是將未更改的屬性標記爲未修改。

可以說你有這些屬性的模型:Id,Name,Email。你不想改變電子郵件。

public ActionResult ChangeName([Bind(Include="Id,Name")] User model) 
{ 
    // ... 
    db.Entry(model).State = EntityState.Modified; 
    db.Entry(model).Property(m => m.Email).IsModified = false; 
    db.SaveChanges(); 
    // ... 
} 

的缺點是,你可能會碰到因爲在模型中缺失領域的驗證問題。