How can I integrate ASP.NET MVC unobtrusive validation and Twitter Bootstrap? I want to have all those validation messages and styles appropriately.

- 18,024
- 7
- 45
- 70

- 24,674
- 56
- 152
- 266
-
1May be related to this one http://stackoverflow.com/questions/11065442/integrating-twitter-bootstrap-with-asp-net-mvc-3-forms – Sherbrow Jul 13 '12 at 10:11
12 Answers
A nice way of handling this if you're using Bootstrap 2 is...
Add this to your _Layout.cshtml
:
<script type="text/javascript">
jQuery.validator.setDefaults({
highlight: function (element, errorClass, validClass) {
if (element.type === 'radio') {
this.findByName(element.name).addClass(errorClass).removeClass(validClass);
} else {
$(element).addClass(errorClass).removeClass(validClass);
$(element).closest('.control-group').removeClass('success').addClass('error');
}
},
unhighlight: function (element, errorClass, validClass) {
if (element.type === 'radio') {
this.findByName(element.name).removeClass(errorClass).addClass(validClass);
} else {
$(element).removeClass(errorClass).addClass(validClass);
$(element).closest('.control-group').removeClass('error').addClass('success');
}
}
});
$(function () {
$("span.field-validation-valid, span.field-validation-error").addClass('help-inline');
$("div.control-group").has("span.field-validation-error").addClass('error');
$("div.validation-summary-errors").has("li:visible").addClass("alert alert-block alert-error");
});
</script>
These are the posts where I found the code pieces above:
Integrating Bootstrap Error styling with MVC’s Unobtrusive Error Validation
Twitter Bootstrap validation styles with ASP.NET MVC
MVC Twitter Bootstrap unobtrusive error handling
UPDATE
Right now I needed to do the same when using Bootstrap 3. Here's the modifications necessary since the class names changed:
<script type="text/javascript">
jQuery.validator.setDefaults({
highlight: function (element, errorClass, validClass)
{
if (element.type === 'radio')
{
this.findByName(element.name).addClass(errorClass).removeClass(validClass);
} else
{
$(element).addClass(errorClass).removeClass(validClass);
$(element).closest('.form-group').removeClass('has-success').addClass('has-error');
}
},
unhighlight: function (element, errorClass, validClass)
{
if (element.type === 'radio')
{
this.findByName(element.name).removeClass(errorClass).addClass(validClass);
} else
{
$(element).removeClass(errorClass).addClass(validClass);
$(element).closest('.form-group').removeClass('has-error').addClass('has-success');
}
}
});
$(function () {
$("span.field-validation-valid, span.field-validation-error").addClass('help-block');
$("div.form-group").has("span.field-validation-error").addClass('has-error');
$("div.validation-summary-errors").has("li:visible").addClass("alert alert-block alert-danger");
});
</script>

- 1
- 1

- 100,159
- 46
- 371
- 480
-
3also wanted to thank you for the 3.0 version. saved me some time. ;) – Nate Jackson Feb 07 '14 at 02:24
-
1
-
Copy the css of the validators in your css file and change the color accordinlgly. Something like this should do
.field-validation-error {
color: #b94a48;
display: inline-block;
*display: inline;
padding-left: 5px;
vertical-align: middle;
*zoom: 1;
}
.field-validation-valid {
display: none;
}
.input-validation-error {
/*
border: 1px solid #ff0000;
background-color: #ffeeee;
*/
color: #b94a48;
border-color: #b94a48;
}
.input-validation-error:focus {
border-color: #953b39;
-webkit-box-shadow: 0 0 6px #d59392;
-moz-box-shadow: 0 0 6px #d59392;
box-shadow: 0 0 6px #d59392;
}
.validation-summary-errors {
/*font-weight: bold;*/
color: #b94a48;
}
.validation-summary-valid {
display: none;
}

- 9,213
- 4
- 49
- 71
-
Definitely prefer the CSS solution over the JS one for my needs (and not using LESS yet) - thanks! – Samantha Branham Aug 14 '13 at 22:59
-
If your like me and put the user auth fields in the header on the opposing side of the logo. In .field-validation-error you can add position:absolute and a background-color. It won't effect the look of the header. – Jason Foglia Dec 10 '13 at 23:19
I suggest to include Bootstrapper in less format and do the same thing as Iridio suggested but in .less. That way you could have something like:
.validation-summary-errors
{
.alert();
.alert-error();
}
.field-validation-error
{
.label();
.label-important();
}
so when bootstrapper will change you'll pick up the changes automatically.
Regular styles that handle visibility from MVC default Site.css
will stay in place and handle visibility.

- 100,159
- 46
- 371
- 480

- 5,901
- 8
- 45
- 86
-
Personally I prefer to use simply a separate file for something small like this. I agree with [this article](http://daneden.me/2012/05/preprocessors/), but as usual I think it's matter of taste – Iridio Jul 16 '12 at 09:21
-
@Shaddix how can I do that? I have my Bootstrap.css file, And I've just added an Alerts.less file with what you posted. But it doesn't seem to work that way. What is the right way to do it? – Laggel Oct 10 '13 at 16:01
-
You can achieve this without using LESS, or copy-pasting CSS styles or using JavaScript. Please see the answer I have added. – Richard Ev Jan 16 '14 at 16:56
-
Perfect - works great for me even in Bootstrap 3 except that ```alert-error()``` needs to be ```alert-danger()``` and ```label-important()``` needs to be ```label-warning()```. – ProNotion Mar 09 '15 at 17:04
Why not just use css !important and call it a day:
/* Styles for validation helpers
-----------------------------------------------------------*/
.field-validation-error {
color: #f00 !important;
}
.field-validation-valid {
display: none;
}
.input-validation-error {
border: 1px solid #f00 !important;
background-color: #fee !important;
}
.validation-summary-errors {
font-weight: bold;
color: #f00;
}
.validation-summary-valid {
display: none;
}

- 1,149
- 13
- 14
On Bootstrap 3 you have to add:
.validation-summary-errors
{
.alert();
.alert-danger();
}
.field-validation-error
{
.label();
.label-danger();
}
you'll see something like that:

- 5,639
- 3
- 40
- 58
-
Is that part of css? Resharper complains for me that () after alert is an unexpected token. – zaitsman Sep 30 '13 at 12:20
-
It's LESS. You'd have to copy the styles that those alert/alert-danger/label/label-danger cover if you wanted to do this in pure CSS. – Matt Mitchell Oct 02 '13 at 03:05
-
Incidentally this looks quite neat. Doesn't apply `has-error` to the whole control-group, so the label isn't coloured / doesn't use default bootstrap validation styling. Also doesn't cover the field itself but that's pretty trivial as the field will have a class on it anyway. – Matt Mitchell Oct 02 '13 at 03:09
-
1
For the ValidationSummary
, you can use the overload that allows you to specify htmlAttributes
. This allows you to set it to use the Twitter Bootstrap alert css styles.
@Html.ValidationSummary(string.Empty, new { @class = "alert alert-danger" })
A similar overload exists for the ValidationMessage
and ValidationMessageFor
helper methods.

- 52,939
- 59
- 191
- 278
-
It doesn't work if you have the case when validation message split in 2 lines – Vladislav Kostenko Feb 07 '14 at 10:43
-
2
You can integrate MVC3 validation with Bootstrap framework by adding the following javascript to your page (View)
<script>
$(document).ready(function () {
/* Bootstrap Fix */
$.validator.setDefaults({
highlight: function (element) {
$(element).closest("div.control-group").addClass("error");
},
unhighlight: function (element) {
$(element).closest("div.control-group").removeClass("error");
}
});
var current_div;
$(".editor-label, .editor-field").each(function () {
var $this = $(this);
if ($this.hasClass("editor-label")) {
current_div = $('<div class="control-group"></div>').insertBefore(this);
}
current_div.append(this);
});
$(".editor-label").each(function () {
$(this).contents().unwrap();
});
$(".editor-field").each(function () {
$(this).addClass("controls");
$(this).removeClass("editor-field");
});
$("label").each(function () {
$(this).addClass("control-label");
});
$("span.field-validation-valid, span.field-validation-error").each(function () {
$(this).addClass("help-inline");
});
$("form").each(function () {
$(this).addClass("form-horizontal");
$(this).find("div.control-group").each(function () {
if ($(this).find("span.field-validation-error").length > 0) {
$(this).addClass("error");
}
});
});
});
</script>
Besides, on the Views (for example "Create.cshtml") make sure that the fields in the form are formatted as the following...
<div class="editor-label">
@Html.LabelFor(Function(model) model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(Function(model) model.Name)
@Html.ValidationMessageFor(Function(model) model.Name)
</div>

- 4,965
- 17
- 49
- 64
For those using Bootstrap 3, the css classes have changed and the solutions above need modifications to work with Bootstrap 3. I have used the following with success with MVC 4 and Bootstrap 3. See this SO thread for more:
$(function () {
// any validation summary items should be encapsulated by a class alert and alert-danger
$('.validation-summary-errors').each(function () {
$(this).addClass('alert');
$(this).addClass('alert-danger');
});
// update validation fields on submission of form
$('form').submit(function () {
if ($(this).valid()) {
$(this).find('div.control-group').each(function () {
if ($(this).find('span.field-validation-error').length == 0) {
$(this).removeClass('has-error');
$(this).addClass('has-success');
}
});
}
else {
$(this).find('div.control-group').each(function () {
if ($(this).find('span.field-validation-error').length > 0) {
$(this).removeClass('has-success');
$(this).addClass('has-error');
}
});
$('.validation-summary-errors').each(function () {
if ($(this).hasClass('alert-danger') == false) {
$(this).addClass('alert');
$(this).addClass('alert-danger');
}
});
}
});
// check each form-group for errors on ready
$('form').each(function () {
$(this).find('div.form-group').each(function () {
if ($(this).find('span.field-validation-error').length > 0) {
$(this).addClass('has-error');
}
});
});
});
var page = function () {
//Update the validator
$.validator.setDefaults({
highlight: function (element) {
$(element).closest(".form-group").addClass("has-error");
$(element).closest(".form-group").removeClass("has-success");
},
unhighlight: function (element) {
$(element).closest(".form-group").removeClass("has-error");
$(element).closest(".form-group").addClass("has-success");
}
});
}();

- 1
- 1

- 2,115
- 21
- 33
You can add a few classes to your Site.css file:
/* styles for validation helpers */
.field-validation-error {
color: #b94a48;
}
.field-validation-valid {
display: none;
}
input.input-validation-error {
border: 1px solid #b94a48;
}
select.input-validation-error {
border: 1px solid #b94a48;
}
input[type="checkbox"].input-validation-error {
border: 0 none;
}
.validation-summary-errors {
color: #b94a48;
}
.validation-summary-valid {
display: none;
}
FYI: http://weblogs.asp.net/jdanforth/form-validation-formatting-in-asp-net-mvc-5-and-bootstrap-3

- 11
- 1
This will convert ValidationSummary()
to a boostrap alert. You can include a little script to remove unnecessary classes and give a highlight to fields with problems.
@if (ViewData.ModelState.Any(x => x.Value.Errors.Any())) {
<div class="alert alert-danger">
<a href="#" class="close" data-dismiss="alert">×</a>
<h4>Validation Errors</h4>
@Html.ValidationSummary()
</div>
}
<script>
$(".validation-summary-errors").removeClass("validation-summary-errors");
$(".input-validation-error").removeClass("input-validation-error").parent().addClass("has-error");
</script>
See more information at http://chadkuehn.com/convert-razor-validation-summary-into-bootstrap-alert/

- 3,971
- 1
- 36
- 31
This is a neat solution that gives you more control over how the ValidationSummary renders errors to the view. The Unordered List it produced did not look right inside the alert. Therefore, I simply looped through the errors and rendered them how I wanted - using paragraphs in this case. For example:
@if (ViewData.ModelState.Any(x => x.Value.Errors.Any()))
{
<div class="alert alert-danger" role="alert">
<a class="close" data-dismiss="alert">×</a>
@foreach (var modelError in Html.ViewData.ModelState.SelectMany(keyValuePair => keyValuePair.Value.Errors))
{
<p>@modelError.ErrorMessage</p>
}
</div>
}

- 31,121
- 10
- 63
- 72
-
This approach only works with server-side validation, not client-side validation since the if statement can't be evaluated on the client side. – Mike Jan 12 '17 at 18:12
The following worked for me:
$(function () {
// any validation summary items should be encapsulated by a class alert and alert-danger
$('.validation-summary-errors').each(function () {
$(this).addClass('alert');
$(this).addClass('alert-danger');
});
// update validation fields on submission of form
$('form').submit(function () {
if ($(this).valid()) {
$(this).find('div.control-group').each(function () {
if ($(this).find('span.field-validation-error').length == 0) {
$(this).removeClass('has-error');
$(this).addClass('has-success');
}
});
}
else {
$(this).find('div.control-group').each(function () {
if ($(this).find('span.field-validation-error').length > 0) {
$(this).removeClass('has-success');
$(this).addClass('has-error');
}
});
$('.validation-summary-errors').each(function () {
if ($(this).hasClass('alert-danger') == false) {
$(this).addClass('alert');
$(this).addClass('alert-danger');
}
});
}
});
// check each form-group for errors on ready
$('form').each(function () {
$(this).find('div.form-group').each(function () {
if ($(this).find('span.field-validation-error').length > 0) {
$(this).addClass('has-error');
}
});
});
});
var page = function () {
//Update the validator
$.validator.setDefaults({
highlight: function (element) {
$(element).closest(".form-group").addClass("has-error");
$(element).closest(".form-group").removeClass("has-success");
},
unhighlight: function (element) {
$(element).closest(".form-group").removeClass("has-error");
$(element).closest(".form-group").addClass("has-success");
}
});
}();
Taken from http://www.benripley.com/development/javascript/asp-mvc-4-validation-with-bootstrap-3.

- 18,630
- 11
- 38
- 46