问题描述
||
我试图建立一个我有一个文本框和DropDownListFor的Edit视图。我想出了一种方法来填充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正常工作。
解决方法
我在寻找其他东西的同时找到了解决方案,在乔·史蒂文斯(Joe Stevens)的博客中:
使用ViewModel时使用Controller UpdateModel
问题在于:当使用视图模型然后正确绑定属性时,有必要“指示” 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>
,下拉列表由HTML格式的<select>
标记表示。 <select>
包含of7ѭ标签的列表,每个标签包含一个ID和一个文本。当用户选择一个选项并提交表单时,此选项的相应ID将发布到服务器。而且只有ID。因此,您可以期望在Edit
POST操作中获得的只是所选选项的ID。 UpdateModel
所做的只是使用发送的请求参数并将其转换为强类型对象。但是,因为所有这些都是POSTed,所以您就可以获得一个简单的ID。从那里开始,如果要获取相应的模型,则必须使用此ID查询数据存储。因此,您无法得到不存在的东西。