UpdateModel不通过ViewModel更新模型,也不从DropDownListFor更新属性

Zaa*_*aak 1 updatemodel viewmodel asp.net-mvc-3

我正在尝试设置一个编辑视图,我有一个文本框和DropDownListFor.我已经找到了填充DDLF的方法,并且渲染和发布的值是正确的,但我似乎无法让模型正确更新.

我想要更新的对象是从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
Run Code Online (Sandbox Code Playgroud)

我想出更新的唯一方法是从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;
        }
Run Code Online (Sandbox Code Playgroud)

此外,当我尝试更新这样的ID字段时,我得到以下错误:

           zupanija.DrzavaID = Convert.ToInt32(collection["Zupanija.DrzavaID"]);
Run Code Online (Sandbox Code Playgroud)

错误:抛出新的System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();

在我看来,这是非常糟糕的方式,我试图让UpdateModel工作.

Zaa*_*aak 5

我在Joe Stevens的博客中找到了解决方案的同时找到了解决方案:

使用ViewModel时使用Controller UpdateModel

捕获如下:当使用视图模型然后正确绑定属性时,必须"指示"UpdateModel帮助程序如何找到我们希望更新的实际类.

我的解决方案需要修改

 UpdateModel(zupanija); to  UpdateModel(zupanija,"Zupanija");
Run Code Online (Sandbox Code Playgroud)

因为我使用的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>
Run Code Online (Sandbox Code Playgroud)