TryUpdateModel(model,prefix,includeProperties)返回false但某些属性仍然更新

时间:2017-12-21 02:36:28

标签: c# asp.net asp.net-mvc

我有一个场景,我在ASP.NET MVC5应用程序中编辑模型,当我提交空值时TryUpdateModel返回false(正确)但当我返回视图时传入的模型相同TryUpdateModel其中一个属性已更新,但其他属性尚未更新。 - 即使它们都无效。

摄制:

  • 加载/加工/编辑?serialNumber = 2
  • 清除位置和名称字段(手动使用删除,退格或剪切)
  • 点击“更新”按钮提交表单
  • 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);
}

0 个答案:

没有答案