2009-10-13 6 views
0

J'ai une vue pour créer un utilisateur comme suit.Afficher le dictionnaire de données en remplaçant les données du modèle dans ASP.NET MVC

<% using (Html.BeginForm("SaveUser", "Security")) {%> 
    <p> 
     <label for="UserName">UserName:</label> 
     <%= Html.TextBox("UserName") %> 
     <%= Html.ValidationMessage("UserName", "*") %> 
    </p> 
    <p> 
     <label for="Password">Password:</label> 
     <%= Html.TextBox("Password") %> 
     <%= Html.ValidationMessage("Password", "*") %> 
    </p> 
    <p> 
     <input type="submit" value="Create" /> 
    </p> 
<}%> 

Lorsque le bouton « Créer » est cliqué, le formulaire HTML est affiché à une action appelée « SaveUser » qui accepte le verbe « POST » seulement comme suit.

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult SaveUser(UserViewModel user) 
{ 
    //user.Id is zero before save 
    //Save the user. Code omitted... 
    //user.Id is now greater than zero 
    //redirect to edit user view 
    return View("EditUser", user); 
} 

Une fois l'utilisateur enregistré, la page est redirigé vers la vue « EditUser » avec

<p> 
    <label for="Id">Id:</label> 
    <%= Html.Hidden("Id", Model.Id)%> 
</p> 

Voici le problème: la valeur du champ caché maintenu apparaître comme zéro si. Model.Id est supérieur à zéro. Il semblait que quelque chose d'autre soit en train de surcharger la valeur de la vue du modèle. ViewDataDictonary était un suspect. Ainsi, une ligne est ajoutée avant de renvoyer la vue dans l'action comme suit.

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult SaveUser(UserViewModel user) 
{ 
    //user.Id is zero before save 
    //Save the user. Code omitted... 
    //user.Id is now greater than zero 

    //clear the view data 
    ViewData = new ViewDataDictionary(); 
    //redirect to edit user view 
    return View("EditUser", user); 
} 

Effectivement, cela a fonctionné. Le champ masqué a maintenant la valeur de l'ID utilisateur correct.

Nous avons trouvé un moyen de traiter le symptôme, mais où est la source du problème?

Je n'aime pas l'idée d'effacer le dictionnaire de données d'affichage à chaque fois avant de retourner une autre vue.

Répondre

4

après une opération réussie, vous devez utiliser

return RedirectToAction("EditUser", new { id = user.Id }); 

ou un code similaire. Le ModelState actuel est utilisé pour générer une vue et le classeur de modèle n'a pas lié Id.

[Bind(Exclude = "Id")] peut également fonctionner, mais la redirection crée une nouvelle page (n'utilisant pas ModelState en cours) et est une meilleure solution.

Edit:

Si vous ne voulez pas lier objet entier, vous devez utiliser [Bind (Exclude)] ou vous devez simplement définir SaveUser comme SaveUser(string userName, string password) et construire vous-même l'objet UserViewModel. Cela vous évitera les erreurs générées par les classeurs du modèle et les valeurs du modèle, dont vous ne savez pas d'où elles proviennent.

+0

++, c'est la manière préférée de gérer ceci. Il résout également le problème de l'actualisation de la page par l'utilisateur et de la publication par inadvertance du même article. Selon le système, cela pourrait être une mauvaise chose si votre action n'est pas idempotente. –

+0

@LukLed, @Joel: merci les gars pour l'aide. Mon UserViewModel est plus complexe que ce que j'ai posté ici, j'ai donc écrit un classeur de modèle personnalisé. Un de mes amis a trouvé un moyen d'utiliser le classeur par défaut sans le classeur personnalisé, donc je vais travailler sur le changement. –

+0

@LukLed: après avoir utilisé RedirectToAction, le problème persiste et j'ai dû utiliser ViewData = new ViewDataDictionary(); En d'autres termes, l'utilisation de la redirection ne résout pas le problème. Y a-t-il quelque chose qui me manque? –

Questions connexes