Как сохранить исходное значение для некоторого поля при выполнении Edit на MVC?
Как вы знаете, когда мы хотим изменить данные, мы перейдем на страницу редактирования:
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
}
Очевидно, что я не могу отобразить какое-либо поле на моей странице редактирования, используя Скрытый, потому что я не хочу, чтобы он отображался в пользовательском интерфейсе. но при отправке мне все еще нужно сохранить исходное значение. Так есть ли хорошая идея для этого? Благодаря
Update1:
Почему я не могу использовать как
entry.Property(e => e.Password).IsModified = false;
ссылка: qaru.site/info/11942/...
Но он отобразит:
Не удалось выполнить проверку для одного или нескольких объектов. Видеть Свойство EntityValidationErrors для более подробной информации.
Ответы
Ответ 1
Извлеките существующую версию из базы данных, а затем измените только "изменяемые" поля:
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();
}
- Возможно, вы также захотите провести оптимизацию concurrency, чтобы убедиться, что обновляемая версия на самом деле актуальна. В идеале, если у вас есть временная метка, используйте это, в противном случае вы столкнулись со сравнением всех полей.
Edit
См. Также комментарий @Kris и Ric о создании моделей с учетом моделей и, следовательно, НЕ загрязняющих ваши представления объектами ORM/уровня данных. Я также утверждаю, что вам нужно иметь метку времени или хэш через ViewModel, чтобы предотвратить проблему перезаписи last one wins
.
Ответ 2
Вариант 1:
Вы можете использовать атрибут readonly:
Что-то вроде:
@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".
оттуда вы можете установить значения в вашем методе действия [HttpPost], используя (linq или иначе), а затем сохраните в своей базе данных.
Вариант 3: Использование ViewBags
так как вы только хотите отредактировать 2 части своей модели, вы можете просто использовать ViewBag
:
Контроллер:
ViewBag.Item1 = xyz;
ViewBag.Item2 = xyz;
Вид:
@Html.TextBox("Item1")
@Html.TextBox("Item2")
Затем в вашем методе post вы можете добавить их как строковые параметры:
public ActionResult Edit(string Item1, string Item2)
{
...
Ответ 3
Вы можете и на самом деле должны создать определенную модель просмотра для своей страницы редактирования. Как:
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();
}
Ответ 4
Вот что я только что узнал, как сделать для отправки данных в базу данных и исключения других полей. Я только хотел опубликовать 1 изменение в моей базе данных на флаге PIVPrinted.
[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");
Ответ 5
Используя механизм просмотра 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)
Ответ 6
Если вы не хотите использовать скрытое представление, вы должны загрузить yor entity из db и добавить изменения yor, например
var olduser= db.Persons.FirstOrDefault(p => p.id = user.id);
olduser.Name=user.Name;
olduser.Sex=user.Sex;
persons.SaveChanges();
Ответ 7
Для изменения только нескольких полей я использую следующий код, и я думаю, вы тоже можете его использовать.
if (ModelState.IsValid)
{
var action = this.db.DbcontextName.Find(int.Parse(id));
db.Entry(action).Property("Status").CurrentValue = "YourString/Data";
db.SaveChanges()
}
Ответ 8
простое и простое решение - использовать сеансы. В методе Edit get просто создайте сеанс и назначьте значение этого конкретного объекта, например.
Session["ProfilePic"] = personnel.ProfilePic;
теперь в методе Edit Post установите значение
personnel.ProfilePic = Session["ProfilePic"].ToString();
в режиме редактирования почты вы проверите условие, когда ваше конкретное значение объекта равно null.
Ответ 9
@Html.HiddenFor(model => model.UserId)
@Html.HiddenFor(model => model.Password)
@Html.HiddenFor(model => model.AddTime)
Не нужно ничего делать, просто перечислите значения констант как синтаксисы Razor.