【问题标题】:UpdateModel not updating the model via ViewModel and property from DropDownListForUpdateModel 不通过 ViewModel 和 DropDownListFor 的属性更新模型
【发布时间】:2011-05-02 06:36:43
【问题描述】:

我正在尝试设置一个编辑视图,在该视图上我有一个文本框和 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

我想出进行更新的唯一方法是从 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"]);

错误:throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();

在我看来,这是非常糟糕的做法,我正在尝试让 UpdateModel 工作。

【问题讨论】:

    标签: asp.net-mvc-3 viewmodel updatemodel


    【解决方案1】:

    我在寻找其他东西时找到了解决方案,在 Joe Stevens 的博客中:

    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>
    

    【讨论】:

      【解决方案2】:

      下拉列表由 HTML 表单中的 &lt;select&gt; 标记表示。一个&lt;select&gt; 包含一个&lt;option&gt; 标签列表,每个标签都包含一个ID 和一个文本。当用户选择一个选项并提交表单时,该选项的相应 ID 将被 POST 到服务器。而且只有身份证。因此,您可以期望在Edit POST 操作中获得所选选项的 ID。 UpdateModel 所做的只是使用发送的请求参数并将它们转换为强类型对象。但是因为所有 POSTed 都是一个简单的 ID,这就是你所能得到的。从那里开始,如果您想获取相应的模型,则必须使用此 ID 查询数据存储。所以你不能得到不存在的东西。

      【讨论】:

        猜你喜欢
        • 2015-01-26
        • 1970-01-01
        • 2014-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-24
        • 2021-07-14
        相关资源
        最近更新 更多