118 votes

Asp.net MVC ModelState.Claire

Quelqu'un peut-il me donner une brève définition du rôle de la ModelState dans Asp.net MVC (ou un lien vers une). En particulier, j'ai besoin de savoir dans quelles situations il est nécessaire ou souhaitable pour appeler ModelState.Clear().

Peu ouvertes hein... désolé, je pense que cela pourrait aider si vous dire ce que je suis acutally faire:

J'ai une Action de Modifier un Contrôleur appelé "Page". Quand j'ai d'abord voir le formulaire pour modifier la Page de détails tout de charges fines (liaison à un "MyCmsPage" de l'objet). Ensuite je clique sur un bouton qui génère une valeur pour l'un des MyCmsPage de l'objet de champs (MyCmsPage.SeoTitle). Il génère de l'amende et des mises à jour de l'objet et j'ai ensuite retourner le résultat action avec le nouveau modifié la page de l'objet et d'en attendre pertinentes de la zone de texte (rendu à l'aide d' <%= Html.TextBox("seoTitle", page.SeoTitle)%>) à être mis à jour ... mais, hélas, il affiche la valeur de l'ancien modèle qui a été chargé.

J'ai travaillé autour d'elle en utilisant ModelState.Clear() mais j'ai besoin de savoir pourquoi / comment il a travaillé, donc je ne suis pas juste de le faire à l'aveuglette.

PageController:

[AcceptVerbs("POST")]
public ActionResult Edit(MyCmsPage page, string submitButton)
{
    // add the seoTitle to the current page object
    page.GenerateSeoTitle();

    // why must I do this?
    ModelState.Clear();

    // return the modified page object
     return View(page);
 }

Aspx:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyCmsPage>" %>
....
        <div class="c">
            <label for="seoTitle">
                Seo Title</label>
            <%= Html.TextBox("seoTitle", page.SeoTitle)%>
            <input type="submit" value="Generate Seo Title" name="submitButton" />
        </div>

138voto

Tim Scott Points 7043

Je pense que c'est un bug dans MVC. J'ai du mal avec ce problème pendant des heures aujourd'hui.

Compte tenu de ceci:

public ViewResult SomeAction(SomeModel model) 
{
    model.SomeString = "some value";
    return View(model); 
}

La vue affiche avec le modèle d'origine, en ignorant les modifications. J'ai donc pensé que, peut-être qu'il ne m'aime pas en utilisant le même modèle, j'ai donc essayé comme ceci:

public ViewResult SomeAction(SomeModel model) 
{
    var newModel = new SomeModel { SomeString = "some value" };
    return View(newModel); 
}

Et encore le point de vue est rendu avec le modèle d'origine. Ce qui est bizarre est que quand je mets un point d'arrêt dans le point de vue et d'examiner le modèle, il a de la valeur modifiée. Mais le flux de réponse a les anciennes valeurs.

Finalement, j'ai découvert le même travail autour de ce que vous avez fait:

public ViewResult SomeAction(SomeModel model) 
{
    var newModel = new SomeModel { SomeString = "some value" };
    ModelState.Clear();
    return View(model); 
}

Fonctionne comme prévu.

Je ne pense pas que c'est une "fonctionnalité" est-il?

48voto

cottsak Points 5490

ModelState MVC est principalement utilisé pour décrire l'état d'un objet de modèle en grande partie à la question de savoir si l'objet est valide ou pas. Ce tutoriel devrait expliquer beaucoup de choses.

En règle générale, vous ne devriez pas avoir à effacer le ModelState comme il est géré par le moteur MVC pour vous. Effacer manuellement peut provoquer des résultats inattendus lorsque vous essayez de respecter MVC validation de pratiques exemplaires.

Il semble que vous essayez de définir une valeur par défaut pour le titre. Cela doit être fait lorsque le modèle objet est instancié (domaine de la couche de quelque part ou dans l'objet lui-même - sans paramètre ctor), sous l'action telle qu'elle se passe en bas de la page la 1ère fois ou entièrement sur le client (via ajax ou quelque chose), de sorte qu'il apparaisse comme si l'utilisateur a entré et il revient avec la publication des formulaires de collecte. Certains comment votre approche de l'ajout de cette valeur à la réception d'un formulaire de collecte (dans le POST de l'action // Edit) est à l'origine de ce comportement bizarre qui pourrait entraîner un .Clear() figurant à travailler pour vous. Faites-moi confiance, vous ne voulez pas être à l'aide de la claire. Essayez l'une des autres idées.

17voto

Carl Saunders Points 81

Si vous voulez effacer une valeur pour un champ individuel puis j'ai trouvé la technique suivante utiles.

ModelState.SetModelValue("Key", new ValueProviderResult(null, string.Empty, CultureInfo.InvariantCulture));

Note: Changement de la "Clé" pour le nom du champ que vous souhaitez réinitialiser.

6voto

JOBG Points 2667

Bien le ModelState fondamentalement détient l'État actuel du modèle en termes de validation, il est titulaire d'

ModelErrorCollection: Représentent les erreurs lorsque le modèle d'essayer de lier les valeurs. ex.

TryUpdateModel();
UpdateModel();

ou comme un paramètre dans la ActionResult

public ActionResult Create(Person person)

ValueProviderResult: les détails à propos de la tentative de lier le modèle. ex. AttemptedValue, De La Culture, RawValue.

Méthode Clear() doit être utilisée avec prudence car elle peut conduire à unspected résultats. Et vous perdrez quelques belles propriétés de la ModelState comme AttemptedValue, il est utilisé par MVC en arrière-plan pour repeupler les valeurs d'un formulaire en cas d'erreur.

ModelState["a"].Value.AttemptedValue

6voto

stevieg Points 31

J'ai eu un cas où je voulais mettre à jour le modèle d'une soumise forme, et ne veulent pas le "Rediriger À l'Action" pour performanace raison. Valeurs précédentes des champs cachés ont été retenus sur mon modèle mis à jour causant allsorts de questions!.

Quelques lignes de code rapidement identifié les éléments à l'intérieur ModelState que j'ai voulu supprimer (après validation), de sorte que les nouvelles valeurs ont été utilisés sous la forme:-

while (ModelState.FirstOrDefault(ms => ms.Key.ToString().StartsWith("SearchResult")).Value != null)
{
    ModelState.Remove(ModelState.FirstOrDefault(ms => ms.Key.ToString().StartsWith("SearchResult")));
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X