我正在尝试设置一个Edit视图,我在其上有一个文本框和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"]);
错误:抛出新的System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
在我看来,这是非常糟糕的方式,我想让UpdateModel工作。
答案 0 :(得分:5)
我在寻找其他东西时找到了解决方案,在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>
答案 1 :(得分:1)
下拉列表由HTML表单中的<select>
标记表示。 <select>
包含<option>
个标记列表,每个标记都包含ID和文本。当用户选择一个选项并提交表单时,该选项的相应ID将被POST到服务器。而且只有身份证。因此,您在Edit
POST操作中可以获得的是所选选项的ID。而UpdateModel
所做的就是使用发送的请求参数并将它们转换为强类型对象。但是因为所有这一切都是一个简单的ID就是你能得到的。从那里开始,如果要获取相应的模型,则必须使用此ID查询数据存储。所以你不能得到一些不存在的东西。