【问题标题】:will form collection takes precedence over the model when using html.hiddenfor使用 html.hiddenfor 时,表单集合优先于模型
【发布时间】:2015-02-03 12:21:05
【问题描述】:

我知道 asp.net mvc web 应用程序中的 html 助手,例如 Html.EditorFor Html.TextBoxFor 等会查看表单集合,如果找不到值,它将使用模型值,除非调用 @987654321 @ 但现在我有以下后期编辑操作方法,我正在检查并发异常:-

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(Skill skill)
{
  try
  {
    var dbskill = db.Skills.SingleOrDefault(a => a.SkillID == skill.SkillID);
    db.Entry(dbskill).State = EntityState.Detached;
    skill.Created = dbskill.Created;
    skill.Modified = System.DateTime.Now;
    skill.CreatedBy = dbskill.CreatedBy;
    skill.ModifiedBy = staffrepo.GetUserIdByUserName(User.Identity.Name.Substring(User.Identity.Name.IndexOf("\\") + 1));
    skill.DeletedDate = dbskill.DeletedDate;
    skill.IsActive = dbskill.IsActive;
    skill.StatusID = db.SkillStatus.Where(a => a.SkillStatusName.ToLower().StartsWith("pen")).SingleOrDefault().SkillStatusID;
    if (ModelState.IsValid)
    {
      skill.CurrentVersion =  dbskill.CurrentVersion + (Decimal)0.01;
      db.Entry(skill).State = EntityState.Modified;
      await db.SaveChangesAsync();
      return RedirectToAction("Details", new { id =skill.SkillID});
    }
  }        
  catch (DbUpdateConcurrencyException ex)
  {
    var entry = ex.Entries.Single();
    var clientValues = (Skill)entry.Entity;
    var databaseEntry = entry.GetDatabaseValues();
    var databaseValues = (Skill)databaseEntry.ToObject();
    var currentSkillTypename = db.SkillTypes.SingleOrDefault(a => a.SkillTypeID == databaseValues.SkillTypeID).Name;
    var currentSkillStatusname = db.SkillStatus.SingleOrDefault(a => a.SkillStatusID == databaseValues.StatusID).SkillStatusName;
    var currentModifiedByName = db.Staffs.SingleOrDefault(a => a.StaffID == databaseValues.ModifiedBy).SamAccUserName;
    if (databaseEntry == null)
    {
      ModelState.AddModelError(string.Empty, "Unable to save changes. The department was deleted by another user.");
    }
    else
    {              
      if (databaseValues.Name != clientValues.Name)
        ModelState.AddModelError("Name", "Current value: " + databaseValues.Name);

      //code goes here...........
      ModelState.AddModelError(string.Empty, "The record you attempted to edit "
      + "was modified by another user after you got the original value. The "
      + "edit operation was canceled and the current values in the database "
      + "have been displayed. If you still want to edit this record, click "
      + "the Save button again. Otherwise click the Back to List hyperlink.");
      skill.timestamp = databaseValues.timestamp;
    }
  }
  catch (Exception e)
  {
    var c = e;
  }
  //
  return View(skill);
}

我感到困惑的是在异常中使用它:-

 skill.timestamp = databaseValues.timestamp

现在,由于我在视图上使用 hiddenfor 将时间戳传递给后期编辑操作方法,因此这意味着 Skill.timestamp 将始终相同,用户将始终收到并发异常,因为 Html. Hiddenfor 将始终从模型中读取值,因此时间戳将始终相同,但发生的情况是在第一次并发异常之后,并且如果用户单击保存,那么第二次他的修改将被保存。 ..那么有人可以就此提出建议吗?

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-5 html-helper modelstate


    【解决方案1】:

    默认情况下,值提供者集合按以下顺序评估来自各种来源的值:

    • 之前绑定的动作参数,当动作是子动作时

    • 表单字段(Request.Form)

    • JSON 请求正文 (Request.InputStream) 中的属性值, 但仅当请求是 AJAX 请求时

    • 路线数据(RouteData.Values)

    • 查询字符串参数(Request.QueryString)

    • 发布的文件(Request.Files)

    https://msdn.microsoft.com/en-us/magazine/hh781022.aspx

    http://dotnetslackers.com/articles/aspnet/Understanding-ASP-NET-MVC-Model-Binding.aspx

    【讨论】:

    • 好的,谢谢你的回复,但是我在你的列表中看不到模型本身,第二个问题,当我从绑定列表中排除一个属性时,模型绑定器会为其分配一个默认值例如,我的修改值将是“1/1/001 12:00am”,这是否意味着值提供者将从发布的表单中读取修改后的值?或者它会假设它不存在并忽略已经分配的默认值??
    • 如果这个列表是正确的,那么在我的情况下,我将从发布的表单中接收时间戳,并且它将一直相同,,而在我的情况下,时间戳将是引发异常时更改...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多