Как сохранить исходное значение для некоторого поля при выполнении 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.