web-dev-qa-db-fra.com

Comment conserver la valeur d'origine pour certains champs lors de l'exécution de Edit sur MVC?

Comme vous le savez, lorsque nous voulons modifier une donnée, nous allons aller à la page d'édition:

public ActionResult EditAdmin(int UserId)
{ 
        User user = persons.Users.Find(id);
        return View(user);
}

Ensuite, nous le soumettons sur la page d'édition, il sera modifié:

public ActionResult EditAdmin(User user)
{ 
        persons.Entry(user).State = EntityState.Modified;
        persons.SaveChanges();
}

Mais le problème, c’est que j’ai beaucoup de champ n’a pas besoin d’être modifié:

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
}

Évidemment, je ne peux pas afficher certains champs sur ma page d'édition en utilisant Hidden, car je ne souhaite pas qu'il s'affiche sur l'interface utilisateur. mais quand je le soumets, j’en ai toujours besoin garde toujours la valeur originale. Alors, y a-t-il une bonne idée pour cela? Merci

Update1:

Pourquoi je ne peux pas utiliser comme 

entry.Property(e => e.Password).IsModified = false;

lien: https://stackoverflow.com/a/18004476/1900498

Mais il affichera: 

La validation a échoué pour une ou plusieurs entités. Voir Propriété 'EntityValidationErrors' pour plus de détails.

13
qakmak

Récupérez la version existante de la base de données, puis modifiez uniquement les champs 'modifiables':

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();
}
  • Vous pouvez également effectuer une vérification optimiste de la concurrence afin de vous assurer que la version mise à jour est bien à jour. Idéalement, si vous avez un horodatage, utilisez-le, sinon vous devrez comparer tous les champs.

Modifier
Voir également le commentaire de @Kris et le point de vue de Ric sur la création de modèles de vue personnalisés et, partant, de ne PAS polluer vos vues avec des entités ORM/données. Je soutiens également que vous devez effectuer un horodatage ou un hachage dans le ViewModel pour éviter le problème de remplacement last one wins.

18
StuartLC

Option 1:

Vous pouvez utiliser un attribut readonly :

Quelque chose comme:

@Html.EditorFor(model => model.DriverID, new { htmlAttributes = new { 
        @Value = @Html.Action("getNextDriverID"), @readonly = "readonly"} })

Ne vous inquiétez pas pour la partie @Value car cela me permet d'appeler une méthode d'action pour générer automatiquement une valeur. 

Dans votre contexte, le votre ressemblerait à:

@Html.EditorFor(model => model.UserId, new { htmlAttributes = new {@readonly = "readonly"} })

Notez s'il vous plaît

Cette réponse fait référence à l’utilisation de rasoir view engine.


Option 2:

Une autre option serait d’utiliser une viewModel totalement différente:

public class edit User{

    public int userId {get; set;}
    public string Name {get; set;}
    public bool Sex {get; set;}
}

Et ensuite 'remplissez' vos données en utilisant ceci dans votre `Edit ActionResult.

à partir de là, vous pouvez ensuite définir les valeurs dans votre méthode Action [HttpPost] à l'aide de (linq ou autre) avant de les enregistrer dans votre base de données.


Option 3: Utiliser ViewBags

puisque vous ne souhaitez éditer que 2 parties de votre modèle, vous pouvez simplement utiliser la variable ViewBag:

Manette:

ViewBag.Item1 = xyz;
ViewBag.Item2 = xyz;

Vue:

@Html.TextBox("Item1")
@Html.TextBox("Item2")

Ensuite, dans votre méthode post, vous pouvez ajouter les paramètres suivants:

public ActionResult Edit(string Item1, string Item2)
{
 ...
10
user3913686

Vous pouvez et devez réellement créer un modèle de vue spécifique pour votre page de modification. Comme:

public class UserViewModel
{
    public string Name {get; set;}
    public bool Sex {get; set;}
}

Ensuite, au lieu de renvoyer l'utilisateur complet vers et depuis la vue, utilisez 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();
}
6
Ric .Net

Voici quelque chose que je viens d'apprendre à faire pour publier les données dans une base de données et exclure d'autres champs. Je voulais seulement publier 1 changement dans ma base de données sur la case à cocher 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");
3
nolanfilm

En utilisant le moteur de vue Razor, vous pouvez marquer l’entrée comme étant masquée: -

    <div class="form-group" style="visibility:hidden;height:0px;">
            @Html.EditorFor(model => model.CreationDate)
            @Html.ValidationMessageFor(model => model.CreationDate, "", new { @class = "text-danger" })
    </div>

Ou simplement ce qui est plus simple: -

    @Html.HiddenFor(model => model.CreationDate)
2
user2284063

Si vous ne voulez pas utiliser masqué dans la vue, vous devez charger votre entité à partir de la base de données et ajouter vos modifications comme

var olduser= db.Persons.FirstOrDefault(p => p.id = user.id);
olduser.Name=user.Name; 
olduser.Sex=user.Sex;
persons.SaveChanges();
1
M.Azad
 @Html.HiddenFor(model => model.UserId)
 @Html.HiddenFor(model => model.Password)
 @Html.HiddenFor(model => model.AddTime)

Nul besoin de faire autre chose, il suffit de lister les valeurs constantes sous forme de syntaxes Razor.

1
Emre Sevim

solution simple et facile est d'utiliser des sessions. Dans la méthode Edit get, il suffit de créer une session et d'affecter une valeur à cet objet particulier, par exemple.

Session["ProfilePic"] = personnel.ProfilePic;

maintenant dans la méthode Edit Post définir la valeur

personnel.ProfilePic = Session["ProfilePic"].ToString();

hors cours en mode post publication, vous vérifierez la condition lorsque la valeur de votre objet est nulle.

0
Hassan Raza

Pour ne modifier que quelques champs, j'utilise le code suivant et je pense que vous aussi pouvez vous en servir.

if (ModelState.IsValid)
{
    var action = this.db.DbcontextName.Find(int.Parse(id));   
    db.Entry(action).Property("Status").CurrentValue = "YourString/Data";

    db.SaveChanges()          
 }
0
Rom