2011-05-01 51 views
1

我想設置一個編輯視圖,我有一個文本框和DropDownListFor。我已經想出了填充DDLF的方法,並且渲染和發佈的值是正確的,但我似乎無法讓模型正確更新。UpdateModel不更新模型通過ViewModel和DropDownListFor屬性

我試圖更新的對象是從LINQtoSQL生成的,而在數據庫中它有外鍵列。在導致「包含」關係的LINQtoSQL類中。我可以找到代表DB中列的ID屬性,以及它代表的對象。

 zupanija = new Zupanija();  //object that needs to be updated 
     zupanija.Drzava;     //object that i want to change to make the update 
     zupanija.DrzavaID;    //Property linked to object that should change 

只有我已經想通了,做的更新方式是從DDLF獲得的價值,並用它來獲得,我想改變這樣的對象:

 [HttpPost] 
     public ActionResult Edit(int id, FormCollection collection) 
     { 
     var zupanija = repo.ZupanijaById(id); 
     var drzava = new repoDrzava().DrzavaById(Convert.ToInt32(collection["Zupanija.DrzavaID"])); 
     zupanija.Drzava = drzava; 
     } 

而且當我嘗試更新ID字段是這樣,然後我得到如下因素的錯誤:

  zupanija.DrzavaID = Convert.ToInt32(collection["Zupanija.DrzavaID"]); 

錯誤:拋出新System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();

在我看來,這是非常糟糕的方式來做到這一點,我試圖讓UpdateModel工作。

回答

5

我已經由喬·史蒂文斯找到了解決辦法,同時尋找別的東西,在博客:

Using Controller UpdateModel when using ViewModel

美中不足的是以下幾點:當視圖模型被使用,那麼正確綁定屬性,有必要來「指導」UpdateModel幫手如何找到我們希望更新的實際類。

修改

UpdateModel(zupanija); to UpdateModel(zupanija,"Zupanija"); 

需要,因爲我是使用包含幾個屬性與主數據類我想更新沿ViewModel類我的解決辦法。 這裏是代碼,我希望它有助於理解:

public class ZupanijaFVM 
    { 
    public IEnumerable<SelectListItem> Drzave { get; private set; } 
    public Zupanija Zupanija { get; private set; } 
    ... 
    } 

    // From Controller 
    // 
    // GET: /Admin/Zupanije/Edit/5 
    public ActionResult Edit(int id) 
    { 
     var zupanija = repo.ZupanijaById(id); 
     return zupanija == null ? View("Error") : View(new ZupanijaFVM(repo.ZupanijaById(id))); 
    } 

    // 
    // POST: /Admin/Zupanije/Edit/5 

    [HttpPost] 
    public ActionResult Edit(int id, FormCollection collection) 
    { 
     var zupanija = repo.ZupanijaById(id); 
     if (TryUpdateModel(zupanija, "Zupanija")) 
     { 
      repo.Save(); 
      return RedirectToAction("Details", new { id = zupanija.ZupanijaID }); 
     } 
     return View(new ZupanijaFVM(zupanija)); 
    } 

    //From View: 
    @model VozniRed.Areas.Admin.Models.ZupanijeFVM 

    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 
     @using (Html.BeginForm()) 
     { 
     @Html.ValidationSummary(true) 
     <fieldset> 
     <legend>Zupanija</legend> 
      @Html.HiddenFor(model => model.Zupanija.ZupanijaID) 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.Zupanija.Naziv) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Zupanija.Naziv) 
      @Html.ValidationMessageFor(model => model.Zupanija.Naziv) 
     </div> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.Zupanija.Drzava) 
     </div> 
     <div class="editor-field"> 
      @Html.DropDownListFor(model => model.Zupanija.DrzavaID, Model.Drzave) 
      @Html.ValidationMessageFor(model => model.Zupanija.DrzavaID) 
     </div> 
     <p> 
      <input type="submit" value="Save" /> 
     </p> 
     </fieldset> 
     } 
    <div> 
    @Html.ActionLink("Back to List", "Index") 
    </div> 
1

下拉列表由HTML表單中的<select>標記表示。 A <select>包含各自包含ID和文本的<option>標籤的列表。當用戶選擇一個選項並提交表單時,這個選項的相應ID被髮送到服務器。只有身份證。因此,您可以期望在您的Edit POST操作中獲得所選選項的ID。 UpdateModel所做的就是使用發送的請求參數並將它們轉換爲強類型對象。但是因爲所有這些都是一個簡單的ID,所有你可以得到。從那裏開始,如果要獲取相應的模型,則必須使用此ID查詢數據存儲。所以你不能得到一些不存在的東西。