Modèle de réussite de l'Édition sans un tas de champs cachés

En Bref: Comment puis-je modifier avec succès un DB d'entrée sans avoir besoin d'inclure tous les domaines pour le Modèle à l'intérieur de la Vue Edit?

Mise à JOUR

J'ai donc un élément dans la base de données (un Article). Je veux modifier un article. L'article que j'ai modifier a de nombreuses propriétés (Id, CreatedBy, DateCreated, Title, Body). Certaines de ces propriétés n'a jamais besoin de changer (comme Id, CreatedBy, DateCreated). Donc, dans mon Édition de la Vue, et je ne veux champs de saisie pour les champs qui peuvent être modifiés (comme le Titre, le Corps). Quand j'mettre en œuvre une modification en Vue comme cela, le Modèle de la Liaison échoue. Tous les champs que je n'ai pas d'approvisionnement en intrants pour les obtient une valeur "par défaut" (comme DateCreated obtient mis à 01/01/0001 12:00:00). Si je ne approvisionnement en intrants pour chaque champ, tout fonctionne bien, et l'article est modifié comme prévu. Je ne sais pas si c'est correct de dire que "le Modèle de la Liaison échoue" forcément, si bien que "le système remplit les champs avec des données incorrectes si aucun champ de Saisie a été fourni pour eux dans la Vue d'Édition."

Comment puis-je créer une Vue d'Édition d'une façon telle que j'ai seulement besoin de fournir des champs de saisie pour les champs qui peuvent/doivent montage, de sorte que lorsque la modification de la méthode du Contrôleur est appelé, des domaines comme la DateCreated sont correctement renseignées, et pas définie par défaut, valeur incorrecte? Voici ma méthode Edit tel qu'il est actuellement:

    [HttpPost]
    public ActionResult Edit(Article article)
    {
        //Get a list of categories for dropdownlist
        ViewBag.Categories = GetDropDownList();


        if (article.CreatedBy == (string)CurrentSession.SamAccountName || (bool)CurrentSession.IsAdmin)
        {                
            if (ModelState.IsValid)
            {
                article.LastUpdatedBy = MyHelpers.SessionBag.Current.SamAccountName;
                article.LastUpdated = DateTime.Now;
                article.Body = Sanitizer.GetSafeHtmlFragment(article.Body);

                _db.Entry(article).State = EntityState.Modified;
                _db.SaveChanges();
                return RedirectToAction("Index", "Home");
            }
            return View(article);
        }

        //User not allowed to edit
        return RedirectToAction("Index", "Home");   
    }

Et modification de la Vue si cela aide:

. . .
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Article</legend>
<p>
<input type="submit" value="Save" /> | @Html.ActionLink("Back to List", "Index")
</p>
@Html.Action("Details", "Article", new { id = Model.Id })
@Html.HiddenFor(model => model.CreatedBy)
@Html.HiddenFor(model => model.DateCreated)
<div class="editor-field">
<span>
@Html.LabelFor(model => model.Type)
@Html.DropDownListFor(model => model.Type, (SelectList)ViewBag.Categories)
@Html.ValidationMessageFor(model => model.Type)
</span>
<span>
@Html.LabelFor(model => model.Active)
@Html.CheckBoxFor(model => model.Active)
@Html.ValidationMessageFor(model => model.Active)
</span>
<span>
@Html.LabelFor(model => model.Stickied)
@Html.CheckBoxFor(model => model.Stickied)
@Html.ValidationMessageFor(model => model.Stickied)
</span>            
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Title)
@Html.ValidationMessageFor(model => model.Title)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Body)
</div>
<div class="editor-field">
@* We set the id of the TextArea to 'CKeditor' for the CKeditor script to change the TextArea into a WYSIWYG editor. *@
@Html.TextAreaFor(model => model.Body, new { id = "CKeditor", @class = "text-editor" })
@Html.ValidationMessageFor(model => model.Body)
</div>
</fieldset>
. . .

Si je devais quitter ces deux entrées:

@Html.HiddenFor(model => model.CreatedBy)
@Html.HiddenFor(model => model.DateCreated)

lorsque la modification de la méthode est appelée, ils sont définis à leurs valeurs par défaut. CreatedBy est fixé à Null, Créée est fixé à 01/01/0001 12:00:00

Pourquoi ne sont-ils pas les valeurs qu'ils sont actuellement définis dans la DB?

Vous pouvez également utiliser tryupdatemodel pour mettre(existingArticle) au lieu de mettre tous les domaines. Une solution peut ne pas sembler trop élégant, mais il existe des solutions comme AutoMapper, que vous pouvez utiliser plus tard, qui permettra de résoudre ce problème, mais pour l'instant vous n'avez pas à le savent pas encore.
Mais si c'est la "bonne" voie, bien sûr, je veux le savoir maintenant 😉 j'ai été faire un peu de creuser et il semble que, oui, à l'aide de ces choses que l'on appelle "Viewmodel" est le chemin à parcourir: une manière de "montrer une tranche de l'information à partir d'une seule entité". Apparemment, c'est un peu plus de travail, mais aussi de modèles de points de vue deviennent plus complexes qu'ils détiennent fort, alors que ces autres "force brute" méthodes ont tendance à se décomposer.

OriginalL'auteur Caleb Bergman | 2012-06-07