在MVC上执行Edit时,如何保持某些字段的原始值
本文关键字:字段 原始 何保持 MVC 执行 Edit | 更新日期: 2023-09-27 18:27:38
如您所知,当我们想要修改数据时,我们将转到编辑页面:
public ActionResult EditAdmin(int UserId)
{
User user = persons.Users.Find(id);
return View(user);
}
然后我们在编辑页面上提交,它将修改:
public ActionResult EditAdmin(User user)
{
persons.Entry(user).State = EntityState.Modified;
persons.SaveChanges();
}
但问题是,我有很多字段不需要修改:
public class User{
public int UserId {get; set;} // do not need modify
public int Password {get; set;} // do not need modify
public string Name {get; set;}
public bool Sex {get; set;}
public DateTime AddTime {get; set;} // do not need modify
}
很明显,我无法在编辑页面上使用Hidden显示某些字段,因为我不希望它显示在UI上。但在提交时,我仍然需要它仍然保持原始值。有什么好主意吗?感谢
更新1:
为什么我不能像一样使用
entry.Property(e => e.Password).IsModified = false;
链接:https://stackoverflow.com/a/18004476/1900498
但它会显示:
一个或多个实体的验证失败。看见"EntityValidationErrors"属性以获取更多详细信息。
从数据库中获取现有版本,然后只更改"可修改"字段:
public ActionResult EditAdmin(User user)
{
var currentPerson = db.Persons.FirstOrDefault(p => p.id = user.id);
if (currentPerson == null)
return HttpNotFound();
currentPerson.Name = user.Name;
currentPerson.Sex = user.Sex;
// Id and Password are not updated.
db.SaveChanges();
}
- 您可能还想进行一些乐观的并发检查,以确保正在更新的版本实际上是最新的。理想情况下,如果您有一个时间戳,请使用它,否则,您将面临比较所有字段的问题
编辑
另请参阅@Kris的评论和Ric关于创建定制视图模型的观点,从而避免ORM/数据层实体污染您的视图。我仍然认为,您需要在ViewModel中携带时间戳或哈希,以防止last one wins
覆盖问题。
选项1:
您可以使用只读属性:
类似于:
@Html.EditorFor(model => model.DriverID, new { htmlAttributes = new {
@Value = @Html.Action("getNextDriverID"), @readonly = "readonly"} })
不要担心@Value
部分,因为这允许我调用一个操作方法来自动生成值。
在上下文中,您的看起来像:
@Html.EditorFor(model => model.UserId, new { htmlAttributes = new {@readonly = "readonly"} })
请注意
这个答案指的是使用剃刀视图引擎。
选项2:
另一种选择是完全使用不同的viewModel
:
public class edit User{
public int userId {get; set;}
public string Name {get; set;}
public bool Sex {get; set;}
}
然后在"编辑ActionResult"中使用此选项"填充"您的数据。
然后,您可以使用(linq或其他)在[HttpPost]Action方法中设置值,然后保存到数据库中。
选项3:使用ViewBags
由于您只想编辑模型的两个部分,您可能只想使用ViewBag
:
控制器:
ViewBag.Item1 = xyz;
ViewBag.Item2 = xyz;
视图:
@Html.TextBox("Item1")
@Html.TextBox("Item2")
然后在您的post方法中,您可以将这些作为字符串参数添加:
public ActionResult Edit(string Item1, string Item2)
{
...
您可以而且实际上应该为您的编辑页面创建一个特定的视图模型。类似:
public class UserViewModel
{
public string Name {get; set;}
public bool Sex {get; set;}
}
然后,使用UserViewModel,而不是在视图中返回完整的用户。
public ActionResult EditAdmin(int userId)
{
User user = persons.Users.Find(userId);
return View(new UserViewModel
{
Id = user.Id,
Name = user.Name,
Sex = user.Sex
});
}
[HttpPost]
public ActionResult EditAdmin(UserViewModel user)
{
var dbUser = persons.Users.Find(user.Id);
dbUser.Name = user.Name;
dbUser.Sex = user.Sex;
persons.Entry(dbUser).State = EntityState.Modified;
persons.SaveChanges();
}
以下是我刚刚学到的将数据发布到数据库并排除其他字段的方法。我只想在PIVPrinted复选框上对我的数据库进行1次更改。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult PrintDetails([Bind(Include = "PatientID,LastName,FirstName,PatientDOB,PIVCompleted,PIVPrinted")] PIV pIV,
string command)
{
if (command.Equals("Print Completed"))
{
pIV.PIVPrinted = false;
db.Entry(pIV).State = EntityState.Unchanged;
db.Entry(pIV).Property("PIVPrinted").IsModified = true;
db.SaveChanges();
return RedirectToAction("PrintDetails");
使用Razor视图引擎,您可以将条目标记为隐藏:-
<div class="form-group" style="visibility:hidden;height:0px;">
@Html.EditorFor(model => model.CreationDate)
@Html.ValidationMessageFor(model => model.CreationDate, "", new { @class = "text-danger" })
</div>
或者只是这个更简单:-
@Html.HiddenFor(model => model.CreationDate)
如果你不想在视图中使用隐藏,你必须从数据库加载yor实体,并添加像这样的yor更改
var olduser= db.Persons.FirstOrDefault(p => p.id = user.id);
olduser.Name=user.Name;
olduser.Sex=user.Sex;
persons.SaveChanges();
@Html.HiddenFor(model => model.UserId)
@Html.HiddenFor(model => model.Password)
@Html.HiddenFor(model => model.AddTime)
无需做任何其他操作,只需将常量值列为Razor语法即可。
为了修改几个字段,我使用了以下代码,我认为你也可以使用它。
if (ModelState.IsValid)
{
var action = this.db.DbcontextName.Find(int.Parse(id));
db.Entry(action).Property("Status").CurrentValue = "YourString/Data";
db.SaveChanges()
}
简单易行的解决方案是使用会话。例如,在Edit get方法中,只需创建会话并为特定对象赋值。
Session["ProfilePic"] = personnel.ProfilePic;
现在在Edit Post方法中设置值
personnel.ProfilePic = Session["ProfilePic"].ToString();
当然,在Edit post方法中,当您的特定对象值为null时,您将检查条件。
您可以像这样使用TempData:
public ActionResult EditAdmin(int UserId)
{
User user = persons.Users.Find(id);
TempData["oldUser"] = user;
return View(user);
}
然后你可以在张贴后恢复它:
public ActionResult EditAdmin(User user)
{
User oldUser = TempData["oldUser"] == null ? persons.Users.Find(user.UserId) : (User) TempData["oldUser"];
if (oldUser.Sex != user.Sex) doSomething();
persons.Entry(user).State = EntityState.Modified;
persons.SaveChanges();
}
有必要检查TempData["oldUser"]==null,因为在出现错误或用户返回页面的情况下,有时TempData会丢失。