我有一个场景,我在ASP.NET MVC5应用程序中编辑模型,当我提交空值时TryUpdateModel
返回false(正确)但当我返回视图时传入的模型相同TryUpdateModel
其中一个属性已更新,但其他属性尚未更新。 - 即使它们都无效。
摄制:
Name
属性是
即使TryUpdateModel
返回false,也会更新。这是字符串唯一的问题,因为无论我为https://msdn.microsoft.com/en-us/library/system.web.mvc.controller.tryupdatemodel(v=vs.118).aspx#Anchor_12提供MachinePosition
的顺序,我都不会更新includedProperties
属性的问题。其他人都遇到过这种情况 - 感觉我在我的代码中做错了,因为这样的副作用肯定会被记录下来。
我注意到这一点的唯一原因是因为我在尝试进行无效更新后返回到主机器列表,并注意到在调试代码时我们正在为这些机器更新Name
属性并且逐步完成它在备份列表更新/设置时我没有打...非常困惑。
我的模特:
public class Machine
{
[Required]
[Range(0, long.MaxValue)]
[Display(Name = "Serial")]
public long SerialNumber { get; set; }
[Required]
[Range(0, 1000)]
[Display(Name = "Position")]
public int MachinePosition { get; set; } = 0;
[Required]
[Display(Name = "Name")]
public string Name { get; set; }
}
我的观点:
@model MyWebApplication.Machine
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Update @Model.Name</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<!-- Have the serial number shown in a hidden field so that it will be passed through on submit -->
@Html.HiddenFor(model => model.SerialNumber)
<div class="form-group">
@Html.LabelFor(model => model.SerialNumber, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DisplayFor(model => model.SerialNumber, new { htmlAttributes = new { @class = "form-control" } })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.MachinePosition, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.MachinePosition, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.MachinePosition, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Update" class="btn btn-default" />
</div>
</div>
</div>
}
我的控制器:
[HttpPost, ActionName("Edit")]
[ValidateAntiForgeryToken]
public ActionResult EditMachine(long? serialNumber)
{
if (serialNumber == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
// Get by serial
Machine machineToUpdate = MachineRepository.Get(serialNumber.Value);
string failureMessage = $"Model validation failed.";
// Model state is valid at this point because we have the serial set
if (ModelState.IsValid)
{
string oldName = machineToUpdate.Name;
int oldPosition = machineToUpdate.MachinePosition;
if (TryUpdateModel(machineToUpdate, "", new string[] { "Name", "MachinePosition" }))
{
Result result = MachineRepository.UpdateMachine(machineToUpdate);
if (result.ResultCode == ResultTypeEnum.Success)
{
// Update the list used by the view to include the new entry
RestoreDatabaseBackup();
// Use PRG pattern to prevent resubmit on page refresh
return RedirectToAction("Edit", new { serialNumber = serialNumber.Value, machineName = $"{oldName}/{machineToUpdate.Name}" });
}
failureMessage = $"There was an error updating the machine: {result.ResultMessage}";
}
}
// Set failure message
ViewBag.UpdateResultMessage = failureMessage;
ViewBag.UpdateSucceeded = false;
// When I get to here the "Name" field has been overwritten with a blank value
return View(machineToUpdate);
}