2010-06-17 16 views
1

OK, commençons par la Html.Textbox. Il est censé contenir du texte lu dans un fichier. Le fichier lu est basé sur ce que l'utilisateur choisit dans une liste déroulante.MVT Html.textbox/dropdown/quel ne sera pas actualiser sur la publication

La première fois c'est bien. L'utilisateur sélectionne une valeur dans la liste déroulante. Le contrôleur utilise cette valeur pour lire du texte à partir d'un fichier et renvoie ce texte à la vue via le modèle de vue. Tout va bien.

Puis l'utilisateur sélectionne une autre valeur dans la liste déroulante. Le contrôleur lit une nouvelle valeur dans un fichier et la renvoie via le modèle de vue. Le débogage à la ligne AVANT que HTML.TEXTBOX est défini dans la vue montre que le modèle contient la valeur correcte. Cependant, la zone de texte elle-même affiche toujours la valeur PREVIOUS lorsque la page s'affiche!

Si je passe de Html.Textbox à une entrée simple, tapez = "text" html control, tout fonctionne bien. Ce n'est pas si difficile, mais la même chose arrive avec ma liste déroulante - je ne peux pas définir la valeur sélectionnée dans le code. Il revient toujours à tout ce qui a été choisi en dernier. Le rendu d'une balise "select" avec une liste d'options générée dynamiquement est pénible. J'aimerais pouvoir utiliser Html.Dropdown.

Qu'est-ce qui me manque ici ?? C'est une chose tellement simple dans les webforms!

+0

J'ai le même comportement non intuitif. Sûrement le modèle est ce qu'il devrait être rendu, et le HtmlHelper devrait rendre le modèle? Si Model.CaptchaAttempt == "" avant que Html.TextBoxFor (m => m.CaptchaAttempt) s'exécute, il devrait sûrement rendre une zone de texte avec une valeur vide? Avez-vous résolu le problème? – jamiebarrow

+0

J'ai effectivement trouvé la réponse - j'ai créé un autre thread (http: // stackoverflow.com/questions/3444994/how-to-effacer-textboxes-defined-with-mvc-html-helpers) comme je suppose que j'avais oublié de celui-ci. J'ai utilisé ModelState.SetModelValue pour les champs que je voulais mettre en blanc ou dans un état quelconque. Certains commentateurs pensaient que je devais faire RedirectToAction, mais j'ai répondu que je voulais être capable d'afficher un message de confirmation à l'utilisateur, ce qui nécessiterait de réafficher la même vue. Je pense qu'un message de confirmation est important, donc je l'ai fait de cette façon, même si ce n'est probablement pas une bonne pratique. – Cynthia

Répondre

0

de ce que sur la suite de Charles/Charlino dit:

modèle met à jour l'objet de liaison ModelState, qui contient la validation et le modèle des erreurs de liaison qui sont collectées au cours de modèle de liaison.

À l'intérieur d'une méthode d'action, une liaison de modèle a déjà eu lieu pour mettre à jour le modèle et générer l'objet ModelState. Si vous mettez à jour la valeur sur le modèle dans l'action, vous devez également mettre à jour manuellement l'état du modèle (puisque les helpers l'utilisent pour générer leur code HTML). Voici un exemple:

model.CaptchaIsValid = CaptchaService.ValidateAndExpireCaptcha(model.CaptchaAttempt); 
if (!model.CaptchaIsValid) 
{ 
    ModelState.AddModelError("CaptchaAttempt", "Incorrect - please try again"); 
} 

// I'll clear the value on each attempt, to force them to re-enter a CAPTCHA. 
model.CaptchaAttempt = string.Empty; 

// Since I updated the model, I must create a new ValueProvider result... 
ValueProviderResult clearedValue = new ValueProviderResult(
     model.CaptchaAttempt, 
     model.CaptchaAttempt, 
     CultureInfo.CurrentCulture); 

// ... and update the ModelState's value. 
ModelState.SetModelValue("CaptchaAttempt", clearedValue); 
-1

Le plus gros problème que je vois ici est que vous essayez de faire une publication dans MVC. Ce modèle n'est vraiment pas pris en charge, et est en fait beaucoup plus de problèmes que cela en vaut la peine (comme il semble que vous découvrez). Je recommande d'utiliser Ajax pour mettre à jour le contenu de la liste déroulante de manière dynamique.

+1

Je ne suis pas d'accord de tout coeur. Vous pouvez faire n'importe quoi dans MVC que vous pouvez faire avec du HTML ordinaire, y compris des publications. Cependant, comme je le découvre, vous ne pouvez pas utiliser les helpers HTML si vous souhaitez définir la valeur des contrôles par programme. Mais j'ai écrit presque une application entière sans AJAX, et c'est tout à fait possible de le faire. – Cynthia

+0

Un POST est une chose HTTP, pas spécifique à MVC ou WebForms. AJAX est une extension au navigateur pour faire des POST (et d'autres demandes) de manière asynchrone. La 'publication' à laquelle vous faites référence est probablement la publication WebForms avec ViewState qui est envoyé d'avant en arrière. MVC n'a pas cette signification que vous devez maintenir l'état manuellement, si elle passe par un HTTP POST standard ou un HTTP asynchrone ... , c'est-à-dire que je suis également en désaccord cordialement. – jamiebarrow

1

Lorsque vous postez un formulaire, les valeurs affichées sont mises en ModelState. Lorsque le HtmlHelper rend un élément iunput html, par ex. Html.TextBoxFor(x => x.FirstName), il va chercher divers endroits pour obtenir la valeur de la zone de texte ... ModelState est avant ViewData.Model dans la liste des emplacements. Alors là, la valeur précédemment affichée apparaîtra dans votre zone de texte. Pour corriger cela, vous pouvez effacer la valeur ModelState ou mettre à jour la valeur ModelState. MAIS je voudrais voir cela comme une manière hacky de contourner le problème.

Le vrai problème a plus à voir avec le flux des messages et des demandes. Je voudrais personnellement examiner cela et peut-être mettre en œuvre le modèle PRG (Post Redirect Get).

HTHS,
Charles