2012-01-09 129 views
0

我有一個詳細信息頁面,可以讓我編輯與特定項目相關的信息。ASP.NET MVC ViewModel更新

public ActionResult Details(int id) 
    { 
     Call call = db.Calls.Find(id); 
     return View(new CallFormViewModel(call)); 
    } 

我用一個視圖模型 -

public class CallFormViewModel 
{ 
    public Call  Call { get; private set; } 

    public CallFormViewModel() 
    { 
     Call = new Call(); 
    } 

    public CallFormViewModel(Call call) 
    { 
     Call = call; 
    } 
} 

當我提出,我想只允許「調用」對象的某些屬性進行更新。我的帖子處理方法是這樣的 -

[HttpPost] 
    public ActionResult Details(CallFormViewModel callForm) 
    { 

     (some code removed for clarity) 

     UpdateModel(callForm.Call ,new string[] { 
      "Contact", 
      "Summary", 
      "Description", 
     } 

    } 

的問題是,callForm已經與所有從表單輸入的更新提交之前,我甚至打電話的UpdateModel。

我該如何改變它並使用UpdateModel來選擇性地更新字段?

感謝

編輯:

我覺得我一直在尋找這個錯誤的方式。我應該做的是:

[HttpPost] 
    public ActionResult Details(int id, CallFormViewModel callForm) 
    { 

     var call = db.Calls.Find(id); 

     (some code removed for clarity) 

     UpdateModel(call, "Call", new string[] { 
      "Contact", 
      "Summary", 
      "Description", 
     } 

    } 

這樣,它採取了不完整的數據[只有田野,我想]並將其應用到實際的模型。我一直在混淆callForm.Call和實際的模型對象,事實上它只是它的一個表示。

必須等到我開始測試這個理論。

+0

您最好使用'AutoMapper'從實體切換到ViewModel。 ViewModel應該是您使用和操作的唯一「數據」,直到您想保存\編輯,然後切換到您保存的真實實體。 AutoMapper幫助將ViewModel從實體中分離出來。希望這個技巧能夠在不久的將來幫助你很多。 – gdoron 2012-01-09 08:37:22

回答

2

當您在Action參數中編寫ViewModel時,Model Binder將ViewModel屬性綁定到「傳入」數據。這應該工作:

[HttpPost] 
public ActionResult Details() 
{ 
    CallFormViewModel callForm = new CallFormViewModel(); 

    UpdateModel(callForm.Call ,new string[] { 
     "Contact", 
     "Summary", 
     "Description", 
    } 
} 

更新:

綁定屬性選項:

[Bind(Include = "Contact,Summary,Description")] 
public class CallFormViewModel 
{ 
    // As before... 
} 
+0

callForm是如何構建的? – NoPyGod 2012-01-09 03:12:07

+0

@NoPyGod,我不確定它必須在之前構建,但你可以「新」它。我更新了。 – gdoron 2012-01-09 03:14:27

+0

如果在CallFormViewModel本身也有相關的屬性,我應該這樣做UpdateModel(callForm,new string [] {「something」,「somethingelse」,「call.contact」,「call.summary」})?當我開始做這樣的事情時,它看起來像是一些非常可惡的代碼。 – NoPyGod 2012-01-09 03:22:04

0

你並不需要調用的UpdateModel因爲你會得到通過更新模型作爲你方法的參數。如果您更喜歡使用UpdateModel,則應從操作方法中刪除參數。

要那麼只更新領域你有興趣,你應該:

  1. 有方法採取只包括應該更新領域的不同視圖模型。
  2. 更改窗體,以便只有要更新的字段位於由HTML.TextBoxFor()方法創建的文本框(或其他可更新控件)中。
+0

你寫的第二個選項是危險的。可能有惡意用戶發送他的數據,如 - 折扣= 100%或?經理=真。第一個選項**(IMO)**太複雜了,有一個實體有兩個視圖模型,只需使用Bind屬性即可。 – gdoron 2012-01-09 03:40:16