I have a MVC4 internet application with a form for creating user accounts. The form validation works but while the input fails validation no error message is displayed. It still prevents submitting until the validation problem is solved but there is no text
Razor View Form
<h2>Create New Account</h2>
<fieldset>
<legend></legend>
@using (Html.BeginForm("CreateUser",null)){
@Html.AntiForgeryToken()
<table class="create">
<tr>
<td colspan="2"><b>New Account</b>
</tr>
<tr>
<td>@Html.DisplayNameFor(model=>model.UserName)</td><td>@Html.TextBoxFor(model=>model.UserName)</td>
<td>@Html.DisplayNameFor(model=>model.EmailAddress)</td><td>@Html.TextBoxFor(model=>model.EmailAddress)</td>
<td><input type="submit" value="Create User" /></td>
</tr>
</table>
}
</fieldset>
@Html.ValidationSummary()
The bundles used include the validation files
bundles.Add(new ScriptBundle("~/bundles/asset").Include(
"~/Scripts/jquery-{version}.js",
"~/Scripts/jquery-ui-{version}.js",
"~/Scripts/jquery.validate*",
"~/Scripts/jquery.unobtrusive*"));
The Model used is an entity model, I have added a partial class to annotate the validation requirements
[MetadataType(typeof(UserProfileMetadata))]
public partial class UserProfile
{
//Empty Class just required for adding class level attribute
}
public class UserProfileMetadata
{
//Fields from user profile requiring annotations
[EmailAddress]
[Required]
[Display(Name = "Email Address")]
public string EmailAddress { get; set; }
[Required]
public string UserName { get; set; }
}
The validation working but now showing the message makes me think it must be a markup error but I just can't see it.
Moving the ValidationSummary inside the form will fix it.
<h2>Create New Account</h2>
<fieldset>
<legend></legend>
@using (Html.BeginForm("CreateUser",null)){
@Html.ValidationSummary()
@Html.AntiForgeryToken()
<table class="create">
<tr>
<td colspan="2"><b>New Account</b>
</tr>
<tr>
<td>@Html.DisplayNameFor(model=>model.UserName)</td> <td>@Html.TextBoxFor(model=>model.UserName)</td>
<td>@Html.DisplayNameFor(model=>model.EmailAddress)</td><td>@Html.TextBoxFor(model=>model.EmailAddress)</td>
<td><input type="submit" value="Create User" /></td>
</tr>
</table>
}
</fieldset>
For anyone stumbling across this who does not wish to be restricted to moving the @Html.ValidationSummary
into the form, i.e. it lives in _Layout.cshtml, and you like it there, here's a way around that.
The below method is apparently what is used by Microsoft to populate @Html.ValidationSummary
. In it's standard form, it looks for data-valmsg-summary-true
in $('this')
. this
in this case is the calling form. Well, my @Html.ValidationSummary
lives in the pageBody
<div>
on _Layout.cshtml to keep it DRY.
function onErrors(event, validator) { // '#pageBody' is the containing element
var container = $('#pageBody').find("[data-valmsg-summary=true]"),
list = container.find("ul"); if (list && list.length && validator.errorList.length) {
list.empty(); container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
$.each(validator.errorList, function () {
$("<li />").html(this.message).appendTo(list);
});
}
}
So far, I've only changed this:
var container = $('this').find("[data-valmsg-summary=true]")
to this:
var container = $('#pageBody').find("[data-valmsg-summary=true]")
Now, I trigger my validation from a button click. To get onErrors(event, validator)
to fire, I used the following jQuery:
$('#btnSave').click(function () {
if ($('form').valid()) {
// Do stuff
} else {
onErrors(event, $('form').data('validator'));
}
});
Voila, @Html.ValidationSummary populates even when using jQuery.unobtrusive.
A big thanks to Leniel Macaferi for pointing me in the right direction here: http://www.leniel.net/2013/08/customizing-aspnet-mvc-html-validation-summary-with-bootstrap-3-panel.html#sthash.jGRguVuV.qSjYUlhS.dpbs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With