ASP.NET MVC 2 UpdateModel() 不更新内存或数据库中的值
我是 MVC 新手,因此正在学习 NerdDinner 教程,此处。特别是,我在使用 UpdateModel 方法时遇到了问题,该教程的第五部分对此进行了解释。问题是,当我尝试使用 UpdateModel 方法编辑晚餐对象的值时,这些值不会更新,也不会引发异常。
奇怪的是,我在使用教程中介绍的创建或删除功能时没有遇到任何问题。只是更新功能不起作用。
下面,我包含了我正在使用的控制器代码以及视图标记,它包含在 aspx 视图文件和 ascx 部分视图文件中。
这是我的控制器中的代码,称为 DiningController.cs
//
// GET: /Dinners/Edit/2
[Authorize]
public ActionResult Edit(int id)
{
Dinner dinner = dinnerRepository.GetDinner(id);
return View(new DinnerFormViewModel(dinner));
}
//
// POST: /Dinners/Edit/2
[AcceptVerbs(HttpVerbs.Post), Authorize]
public ActionResult Edit(int id, FormCollection formValues)
{
Dinner dinner = dinnerRepository.GetDinner(id);
try
{
UpdateModel(dinner);
var x = ViewData.GetModelStateErrors(); // <-- to catch other ModelState errors
dinnerRepository.Save();
return RedirectToAction("Details", new { id = dinner.DinnerID });
}
catch
{
ModelState.AddRuleViolations(dinner.GetRuleViolations());
return View(new DinnerFormViewModel(dinner));
}
}
: 在从另一个 StackOverflow 线程读取可能的解决方案后添加了注释“捕获其他 ModelState 错误”,此处:
ASP.NET MVC Updatemodel 不更新但不抛出错误
不幸的是,该解决方案对我没有帮助。
这是我的 Dinings/Edit.aspx 视图中的相应标记:
<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">
<h2>Edit Dinner</h2>
<% Html.RenderPartial("DinnerForm"); %>
</asp:Content>
这是我的 DiningForm.ascx 部分视图中的相应标记。 此部分视图文件也由“创建”功能使用,运行良好:
<%=Html.ValidationSummary("Please correct the errors and try again.") %>
<% using (Html.BeginForm()) { %>
<fieldset>
<p>
<label for="Title">Dinner Title:</label>
<%=Html.TextBoxFor(model => Model.Dinner.Title)%>
<%=Html.ValidationMessage("Title", "*") %>
</p>
<p>
<label for="EventDate">EventDate:</label>
<%=Html.TextBoxFor(model => Model.Dinner.EventDate, new { value = String.Format("{0:g}", Model.Dinner.EventDate) })%>
<%=Html.ValidationMessage("EventDate", "*") %>
</p>
<p>
<label for="Description">Description:</label>
<%=Html.TextBoxFor(model => Model.Dinner.Description)%>
<%=Html.ValidationMessage("Description", "*")%>
</p>
<p>
<label for="Address">Address:</label>
<%=Html.TextBoxFor(model => Model.Dinner.Address)%>
<%=Html.ValidationMessage("Address", "*") %>
</p>
<p>
<label for="Country">Country:</label>
<%=Html.DropDownListFor(model => Model.Dinner.Country, Model.Countries)%>
<%=Html.ValidationMessage("Country", "*") %>
</p>
<p>
<label for="ContactPhone">ContactPhone #:</label>
<%=Html.TextBoxFor(model => Model.Dinner.ContactPhone)%>
<%=Html.ValidationMessage("ContactPhone", "*") %>
</p>
<p>
<label for="Latitude">Latitude:</label>
<%=Html.TextBoxFor(model => Model.Dinner.Latitude)%>
<%=Html.ValidationMessage("Latitude", "*") %>
</p>
<p>
<label for="Longitude">Longitude:</label>
<%=Html.TextBoxFor(model => Model.Dinner.Longitude)%>
<%=Html.ValidationMessage("Longitude", "*") %>
</p>
<p>
<input type="submit" value="Save"/>
</p>
</fieldset>
<% } %>
无论如何,我已经为此花费了几个小时,但我已经没有想法了。因此,我希望这里有人可以帮助我朝正确的方向推动,以便找出我做错了什么。
I am new to MVC, and so am working through the NerdDinner tutorial, here. In particular, I'm running into problems with the use of the UpdateModel method, which is explained in the part five of that tutorial. The problem is, when I try to edit the value of a dinner object using the UpdateModel method, the values do not get updated, and no exceptions are thrown.
Oddly, I am not having any trouble with the Create or Delete features that are illustrated in the tutorial. Only the update feature isn't working.
Below, I have included the Controller code that I am using, as well as the view markup, which is contained in both an aspx View file and an ascx Partial View file.
Here is the code inside my Controller, called DinnerController.cs:
//
// GET: /Dinners/Edit/2
[Authorize]
public ActionResult Edit(int id)
{
Dinner dinner = dinnerRepository.GetDinner(id);
return View(new DinnerFormViewModel(dinner));
}
//
// POST: /Dinners/Edit/2
[AcceptVerbs(HttpVerbs.Post), Authorize]
public ActionResult Edit(int id, FormCollection formValues)
{
Dinner dinner = dinnerRepository.GetDinner(id);
try
{
UpdateModel(dinner);
var x = ViewData.GetModelStateErrors(); // <-- to catch other ModelState errors
dinnerRepository.Save();
return RedirectToAction("Details", new { id = dinner.DinnerID });
}
catch
{
ModelState.AddRuleViolations(dinner.GetRuleViolations());
return View(new DinnerFormViewModel(dinner));
}
}
The
line with the comment "to catch other ModelState errors" was added after reading a possible solution from another StackOverflow thread, here:
ASP.NET MVC Updatemodel not updating but not throwing error
Unfortunately, that solution didn't help me.
Here is the corresponding markup in my Dinners/Edit.aspx View:
<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">
<h2>Edit Dinner</h2>
<% Html.RenderPartial("DinnerForm"); %>
</asp:Content>
Here is the corresponding markup in my DinnerForm.ascx Partial View. This Partial View file is also used by the Create feature, which is working fine:
<%=Html.ValidationSummary("Please correct the errors and try again.") %>
<% using (Html.BeginForm()) { %>
<fieldset>
<p>
<label for="Title">Dinner Title:</label>
<%=Html.TextBoxFor(model => Model.Dinner.Title)%>
<%=Html.ValidationMessage("Title", "*") %>
</p>
<p>
<label for="EventDate">EventDate:</label>
<%=Html.TextBoxFor(model => Model.Dinner.EventDate, new { value = String.Format("{0:g}", Model.Dinner.EventDate) })%>
<%=Html.ValidationMessage("EventDate", "*") %>
</p>
<p>
<label for="Description">Description:</label>
<%=Html.TextBoxFor(model => Model.Dinner.Description)%>
<%=Html.ValidationMessage("Description", "*")%>
</p>
<p>
<label for="Address">Address:</label>
<%=Html.TextBoxFor(model => Model.Dinner.Address)%>
<%=Html.ValidationMessage("Address", "*") %>
</p>
<p>
<label for="Country">Country:</label>
<%=Html.DropDownListFor(model => Model.Dinner.Country, Model.Countries)%>
<%=Html.ValidationMessage("Country", "*") %>
</p>
<p>
<label for="ContactPhone">ContactPhone #:</label>
<%=Html.TextBoxFor(model => Model.Dinner.ContactPhone)%>
<%=Html.ValidationMessage("ContactPhone", "*") %>
</p>
<p>
<label for="Latitude">Latitude:</label>
<%=Html.TextBoxFor(model => Model.Dinner.Latitude)%>
<%=Html.ValidationMessage("Latitude", "*") %>
</p>
<p>
<label for="Longitude">Longitude:</label>
<%=Html.TextBoxFor(model => Model.Dinner.Longitude)%>
<%=Html.ValidationMessage("Longitude", "*") %>
</p>
<p>
<input type="submit" value="Save"/>
</p>
</fieldset>
<% } %>
In any case, I've been hitting away at this for hours, and I'm out of ideas. So, I'm hoping someone here can help nudge me in the right direction, in order to figure out what I'm doing wrong.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
dinnerRepository.Save()
是实际更新数据库的代码。UpdateModel(dinner)
的作用是从表单集合中提取值并将它们放入您的dinner
对象中。dinnerRepository.Save()
is the code the actually updates the database. WhatUpdateModel(dinner)
does is extract the values from the form collection and put them in yourdinner
object.你把事情搞混了。您正在发送 DiningFormViewModel 到 View,但试图接收晚餐。像这样更改您的发布方法:
这里可能有一些我错过的东西,现在不记得 DiningFormViewModel。请检查这些
编辑:实际上我意识到这篇文章并没有真正解决问题。问题中发布的代码对我有用。有问题但不是这里。
You got something mixed up. You are sending DinnerFormViewModel to View but trying to receive Dinner.Change your post method like this:
There may be something I missed here, don't remember DinnerFormViewModel right now. Please check those
edit: Actually I realized this post doesn't solve the problem really. The code posted in the question works for me. There is a problem but but not here.
以防万一它将来对其他人有帮助,这里的问题不一定是由于使用了 DiningFormViewModel,正如我怀疑的那样。相反,问题在于使用强类型帮助器方法,例如 Html.TextBoxFor 以及我调用 UpdateModel 方法的方式。
StackOverflow 中的另一个线程
Just in case it helps someone else in the future, the problem here was not necessarily due to the use of a DinnerFormViewModel, as I suspected. Rather, the problem was with the use of strongly-typed helper methods, such as Html.TextBoxFor and the way I was invoking the UpdateModel method.
This problem and it's solution is explained in detail in another thread in StackOverflow, here.