.entrée à une erreur de validation d'une zone de texte lorsque le formulaire est réaffiché de l'échec de la valeur
J'ai demandé à un question de savoir pourquoi, dans mon application, les zones de texte sont mis en évidence (c'est à dire à bordure rouge et rose à l'ombre des fond sont appliqués à la zone de texte) lorsque j'utilise modelbinding à la validation du modèle (tryupdatemodel pour mettre()) mais pas quand je valide manuellement (ModelState.AddModelError). Il a été 2 jours sans aucune réponse. J'ai essayé de chaque chose moi-même, sans succès. Donc, je décide de me poser la question différemment.
La façon dont je le comprends, voici comment ModelBinding traite une demande.
- ModelBinding obtenir les valeurs de httpcontext
- Il instancier un objet de ce modèle
- Tente d'analyser ces valeurs à l'objet
- Si il ya quelque chose de mal avec une propriété, il utilise ModelState.AddModelError pour marquer des propriétés qui a quelque chose de mal avec eux.
- Ré-affiche la vue
Voici ma question Lorsque le formulaire est affiché à nouveau:
Ce qui est fait pour les zones de texte dont les valeurs ne sont pas valides pour obtenir mis en avant?
Je sais qu'il y a peu de classes dans le Site.css, comme .entrée à une erreur de validation et .terrain à une erreur de validation qu'appliquée à la zone de texte. Peut-être ModelBinding utilise en interne une commande telle que AddCss("#MyTextBox", ".entrée à une erreur de validation").
Si je sais comment il fonctionne, je peux (peut-être) effectuée manuellement et résoudre mon problème.
MODIFIER
Comme demandé par @Ian Galloway, voici le code
public class RegistrationController : Controller
{
public FormViewModel formViewModel;
private RegistrationService _registrationService = new RegistrationService();
private SaveService _saveService = new SaveService();
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
var serialized = Request.Form["formViewModel"];
if (serialized != null)
{
formViewModel = (FormViewModel)new MvcSerializer()
.Deserialize(serialized);
TryUpdateModel(formViewModel);
}
else
formViewModel = (FormViewModel)TempData["formViewModel"]
?? new FormViewModel();
}
protected override void OnResultExecuted(ResultExecutedContext filterContext)
{
if (filterContext.Result is RedirectToRouteResult)
TempData["formViewModel"] = formViewModel;
}
public ActionResult SetUpOrganization(string cancel, string nextButton)
{
if ((nextButton != null) && ModelState.IsValid)
{
if (formViewModel.navigationData.IsAReview)
return RedirectToAction("RequestPreview");
return RedirectToAction("ChooseTypeOrganization");
}
ViewData["Cities"] = _registrationService.Get_Cities();
formViewModel.navigationData.NextAction = "SetUpOrganization";
return View(formViewModel);
}
public ActionResult ChooseTypeOrganization(string backButton, string nextButton)
{
if (backButton != null)
{
return RedirectToAction("SetUpOrganization");
}
if (nextButton != null)
{
if (formViewModel.navigationData.IsAReview)
return RedirectToAction("RequestPreview");
return RedirectToAction("DocumentsPresented");
}
ViewData["TypeOrganization"] = _registrationService.Get_AllTypeOrganization();
formViewModel.navigationData.NextAction = "ChooseTypeOrganization";
return View(formViewModel);
}
public ActionResult DocumentsPresented(string backButton, string nextButton)
{
if (backButton != null)
{
return RedirectToAction("ChooseTypeOrganization");
}
if (nextButton != null)
{
//Validation
if (string.IsNullOrEmpty(formViewModel.registrationData.DocumentPresente))
{
ModelState.AddModelError("DocumentPresente", "Veuillez préciser votre
autorisation");
return View(formViewModel);
}
//Navigation
if (formViewModel.navigationData.IsAReview)
return RedirectToAction("RequestPreview");
return RedirectToAction("PeopleRecommended");
}
formViewModel.navigationData.NextAction = "DocumentsPresented";
return View(formViewModel);
}
public ActionResult PeopleRecommended(string backButton, string nextButton, string deleteButton,
string deletePerson, string addPerson)
{
if (backButton != null)
{
return RedirectToAction("DocumentsPresented");
}
if (nextButton != null)
{
ModelState.Clear();
if (formViewModel.registrationData.PeopleRecommended.Count == 0)
ModelState.AddModelError("", "Il faut absolument designer un responsable pour la requête");
//
if (ModelState.IsValid)
{
if (formViewModel.navigationData.IsAReview)
return RedirectToAction("RequestPreview");
return RedirectToAction("StateObjectifs");
}
else
{
return View(formViewModel);
}
}
//
if (addPerson != null)
{
if (ModelState.IsValid)
{
formViewModel.registrationData.PeopleRecommended.Add(
_registrationService.Translate_PersonToBeAdded_Into_Person(formViewModel.personToBeAdded)
);
formViewModel.personToBeAdded = null;
}
else
{
formViewModel.navigationData.NextAction = "PeopleRecommended";
return View(formViewModel);
}
}
if (deleteButton != null)
{
formViewModel.registrationData.PeopleRecommended.RemoveAt(int.Parse(deletePerson));
}
ViewData.ModelState.Clear();
formViewModel.navigationData.NextAction = "PeopleRecommended";
return View(formViewModel);
}
[ValidateInput(false)]
public ActionResult StateObjectifs(string backButton, string nextButton)
{
if (backButton != null)
{
return RedirectToAction("PeopleRecommended");
}
if (nextButton != null)
{
if (string.IsNullOrEmpty(formViewModel.registrationData.Objective) ||
string.IsNullOrEmpty(formViewModel.registrationData.RequestDetails))
{
if (string.IsNullOrEmpty(formViewModel.registrationData.Objective))
ModelState.AddModelError("Objective", "Vous devez préciser l'objectif de votre requête");
if (string.IsNullOrEmpty(formViewModel.registrationData.RequestDetails))
ModelState.AddModelError("RequestDetails", "Vous devez préciser le contenu de votre requête");
return View(formViewModel);
}
if (formViewModel.navigationData.IsAReview)
return RedirectToAction("RequestPreview");
return RedirectToAction("StateDeadLine");
}
return View(formViewModel);
}
public ActionResult StateDeadLine(string backButton, string nextButton)
{
if (backButton != null)
{
return RedirectToAction("StateObjectifs");
}
if (nextButton != null)
{
if (formViewModel.registrationData.ChooseDifferentDeadLine)
{
if (formViewModel.registrationData.DifferentDeadline == null ||
string.IsNullOrEmpty(formViewModel.registrationData.ReasonsForDifferentDeadLine))
{
if (formViewModel.registrationData.DifferentDeadline == null)
ModelState.AddModelError("DifferentDeadline", "Clickez pour choisir une nouvelle date");
if (string.IsNullOrEmpty(formViewModel.registrationData.ReasonsForDifferentDeadLine))
ModelState.AddModelError("ReasonsForDifferentDeadLine", "Expliquez brievement pour quoi ce changement");
return View(formViewModel);
}
}
return RedirectToAction("RequestPreview");
}
formViewModel.navigationData.NextAction = "StateDeadLine";
return View(formViewModel);
}
public ActionResult RequestPreview(string backButton, string nextButton, string reviewInput, string save)
{
if (backButton != null)
{
return RedirectToAction("StateDeadLine");
}
if (nextButton != null)
{
_saveService.Save_FormViewModel(formViewModel);
return RedirectToAction("Index", "Home");
}
if (reviewInput != null)
{
formViewModel.navigationData.IsAReview = true;
return RedirectToAction(RedirectHelpers.RedirectReviewAction(formViewModel.navigationData, reviewInput));
}
ViewData["TypeOrganization_Summary"] = _registrationService.Get_TypeOrganization_Summary(
formViewModel.registrationData.TypeOrganizationID );
if (save != null)
{
_saveService.Save_FormViewModel(formViewModel);
return RedirectToAction("Index", "Home");
}
formViewModel.navigationData.NextAction = "RequestPreview";
return View(formViewModel);
}
}
MODIFIER le numéro 2
J'ai choisi l'un de la vue (comme tous de rencontrer le même problème). La vue est appelée StateObjectifs.aspx
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<!-- Script Begin -->
<script src="../../Scripts/tiny_mce/tiny_mce.js" type="text/javascript"></script>
<script type = "text/javascript">
tinyMCE.init({
mode: "textareas",
theme: "advanced",
theme_advanced_toolbar_location: "top",
theme_advanced_toolbar_align: "left",
theme_advanced_statusbar_location: "bottom",
theme_advanced_resizing: true
});
</script>
<!-- End Script -->
<fieldset id = "StateObjectifs">
<legend>Etape 5:</legend>
<div id = "left-pane" style = "width:700px">
<%using (Html.BeginForm("StateObjectifs", "Registration"))
{ %>
<%: Html.ValidationSummary() %>
<% = Html.Serialize("formViewModel", Model) %>
<table>
<tr>
<th><% = Html.LabelFor(x=>x.registrationData.Objective) %></th>
<td><% = Html.TextBoxFor(x=>x.registrationData.Objective) %>
<%: Html.ValidationMessageFor(x =>x.registrationData.Objective, "*")%></td>
</tr>
<tr>
<th colspan = "2"><% = Html.LabelFor(x =>x.registrationData.RequestDetails) %></th>
</tr>
<tr>
<td colspan = "2">
<% = Html.TextAreaFor(x =>x.registrationData.RequestDetails, 10, 75, null) %>
</td>
</tr>
</table>
</div>
<div id = "right-pane">
<ul>
<li>Les cases pour lesquelles le titre se termine par (*) sont obligatoires</li>
<li>Pour mieux vous servir, veuillez décrire clairement de manière concise
votre requête. Par exemple: <i>Les données de l'USAID sur le secteur santé pour l'année 2009</i></li>
</ul>
</div>
<div class = "clear"></div>
<fieldset>
<% Html.RenderPartial("NavigationView", Model.navigationData); %>
</fieldset>
</fieldset>
<%} %>
Merci pour votre aide.
Galloway: cochez la Case modifier ci-dessus
Galloway: j'essaie de poster le code, mais le formatage n'est pas bon. Je vais donc essayer de sélectionner une partie du code et de les écrire à la main, au lieu de copier/coller tout.
Cheers: je vais avoir besoin de la partie de la vue lorsque vous effectuez le rendu de la zone de texte.
OriginalL'auteur Richard77 | 2010-08-13
Vous devez vous connecter pour publier un commentaire.
En fait, ce soulignant est effectuée par le html helpers qui rendent les zones de texte. Il vérifie si il y a une erreur dans le modèle de l'état avec la clé donnée, et il ajoute le nécessaire classes CSS si nécessaire.
Si vous utilisez
TryUpdateModel
est là une erreur ajouté à la ModelState dictionnaire avec la clé donnée? Si non, puis c'est probablement la raison pour laquelle le code HTML helpers ne pas le ramasser.Oui. Actuellement, les deux tryupdatemodel pour mettre et ModelState.AddModelError ajouter des erreurs à la ModelSate. Et, dans les deux cas, Html.ValidateSummary() affiche des messages d'erreur en haut du formulaire. Toutefois, Html.validateMessageFor() ne fonctionne que lorsque j'utilise tryupdatemodel pour mettre, pas avec ModelState.AddModelError(). De la même manière, les zones de texte sont mis en évidence qu'avec tryupdatemodel pour mettre, pas avec ModelState.AddModelError().
Êtes-vous à l'aide de certains complexes de types de modèle? Si donc, dans les deux cas, la clé de points à l'erreur de l'élément dans le
ModelState
dictionnaire de même? Probablement il y a un préfixe ajouté à la clé qui correspond exactement à l'id de l'entrée lors de l'utilisation deTryUpdateModel
qui n'est pas le cas lorsque vous ajoutez manuellement l'erreur à l'aideAddModelError
. LeValidateSummary
helper affiche tous messages d'erreur dans le modèle de l'état.Oui. Depuis que je suis la sérialisation de données lors de l'envoi à la vue d'avant en arrière. J'ai créé 1 modèle qui incluent 3 sous-modèle. De sorte que j'ai de soucier uniquement de la sérialisation de modèle 1, le super-modèle. J'ai posté déjà le contrôleur. Avez-vous besoin également de la vue? le modèle?
OriginalL'auteur Darin Dimitrov
Je soupçonne que le problème que vous rencontrez est la "clé" de paramètre que vous passer dans ModelState.AddModelError doit correspondre au nom du contrôle de la concordance sur la forme.
(Sinon, comment voudriez-vous que le moteur d'affichage de savoir qui contrôle rendu dans un état d'erreur?)
Hm. Pouvez-vous jetez un oeil dans votre balisage et de me dire quel est le nom de code Html.TextBoxFor(x=>x.registrationData.L'objectif), qui vient de sortir?
<input id="registrationData_Objective" name="registrationData.Objectif" type="text" value="" />
Galloway: Merci. de la majoration ci-dessus, j'ai utilisé "registrationData.Objectif", au lieu de simplement "Objectif". Maintenant, il fonctionne. je ne pensais pas qu'il pourrait être facile.
OriginalL'auteur Iain Galloway
La mise en évidence qui est fait en CSS qui s'applique à la zone de texte. Si vous avez besoin d'ajouter le css ci-dessous:
}
OriginalL'auteur Qasim Bataineh