当使用html.hiddenfor时,表单集合优先于模型

时间:2015-02-03 12:21:06

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

我知道asp.net mvc web应用程序中的html帮助程序(如Html.EditorFor Html.TextBoxFor等)会查看表单集合,如果找不到值,它将使用模型值,除非调用{{ 1}}但现在我有以下post edit action方法,我正在检查并发异常: -

modelstate.clear().

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

[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);
}

现在因为我在视图上使用hiddenfor将时间戳传递给post edit动作方法,所以这意味着skill.timestamp将始终是相同的,因为用户将始终收到并发异常,因为Html。 Hiddenfor将始终从模型中读取值,因此时间戳将始终相同,但发生的事情是在第一次并发异常之后,并且如果用户单击“保存”,则第二次将保存其修改。 ..所以有人可以就此提出建议吗?

1 个答案:

答案 0 :(得分:-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