Hello,
I've asked a question to know why, in my application, textboxes are being highlighted (i.e. red border and pink-shaded backgroung are applied to the textbox) when I use modelbinding to validate the model (TryUpdateModel()) but not when I validate manually (ModelState.AddModelError). It has been 2 days now without any answer. I've tried every thing myself without succes. So, I decide to ask the question differently.
The way I understand IT, here's how ModelBinding treats a request.
- ModelBinding get incoming values from httpcontext
- It instantiate an object of that model
- Tries to parse those values to the object
- If there's someting wrong with a property, it uses ModelState.AddModelError to mark properties that has something wrong with them.
- Re-displays the view
Here's my question When the form is re-displayed:
What's being done for the textboxes whose values are not valid to get highlighted?
I know that there's few classes in Site.css, such as .input-validation-error and .field-validation-error that get applied to the textbox. Maybe ModelBinding uses internally a command such as AddCss("#MyTextBox", ".input-validation-error").
If I know how it works, I can (maybe) aplly it manually and solve my problem.
EDIT
As requested by @Ian Galloway, here's the 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);
}
}
EDIT number 2
I have choosed one of the view (as all of them experience the same issue). The view is called 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>
<%} %>
Thanks for helping.