4

I'm new to MVC3, and for the first time I will validate a form. I saw some validation samples using jQuery and using Model.IsValid but I don't know if this is my case.

I'm using @Html.TextBox, and @Html.ValidationMessage, I can see I need to place 2 jQuery lines in my document to validate:

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

And I saw that many people use validation only with jQuery, but I couldn't get how it really works. So, could you please give me a sample validation code for the Razor View with jQuery (if needed) and for Controller? As I'm not using TextBoxFor, I believe I can't use validation only with Datannotations in the Model class.

The form I need to validate:

@Html.TextBox("user", "User:")
@Html.TextBox("email", "Email:") <!-- with validation of email string -->
@Html.Password("password")
@Html.Password("passwordConfirm") <!-- with validation if 2 password strings match -->
Rubia Gardini
  • 815
  • 5
  • 16
  • 30

1 Answers1

17

The jquery.validate.unobtrusive.min.js script works in conjunction with data annotations placed on your model properties. Those validator attributes are then translated by the Html helpers to emit HTML5 data-* attributes which are used by the script. If you don't have a model decorated with validation attributes you cannot use this script.

This being said you could still have a model with validation attributes on it and still use the TextBox instead of TextBoxFor. It would be completely stupid and meaningless but you can do it:

public class MyViewModel
{
    [Required]
    public string MyProperty { get; set; }
}

and then in your view when you use one of the helpers inside a form validation attributes will be emitted:

@model MyViewModel
@using (Html.BeginForm())
{
    @Html.TextBox("MyProperty")
}

If you don't have a view model (don't know why you won't have a view model as this goes against good practices that I preach for) you could manually wire up validation. In this case you simply remove the jquery.validate.unobtrusive script and use the core jquery validate plugin:

$(function() {
    $('#id_of_your_form').validate({
        rules: {
            MyProperty: {
                required: true
            }
        },
        messages: {
            MyProperty: {
                required: 'Please enter a value for MyProperty'
            }
        }
    });
});

Obviously the recommended solution is to use a view model and strongly typed helpers:

public class RegisterViewModel
{
    public string User { get; set; }

    [DataType(DataType.EmailAddress)]
    [Email] // taken from Scott Gu's blog post: http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx
    public string Email { get; set; }

    public string Password { get; set; }

    [Compare("Password")]
    public string PasswordConfirm { get; set; }
}

and then in your view:

@model RegisterViewModel
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm())
{
    <div>
        @Html.LabelFor(x => x.User)
        @Html.EditorFor(x => x.User)
        @Html.ValidationMessageFor(x => x.User)
    </div>
    <div>
        @Html.LabelFor(x => x.Email)
        @Html.EditorFor(x => x.Email)
        @Html.ValidationMessageFor(x => x.Email)
    </div>
    <div>
        @Html.LabelFor(x => x.Password)
        @Html.PasswordFor(x => x.Password)
        @Html.ValidationMessageFor(x => x.Password)
    </div>
    <div>
        @Html.LabelFor(x => x.PasswordConfirm)
        @Html.PasswordFor(x => x.PasswordConfirm)
        @Html.ValidationMessageFor(x => x.PasswordConfirm)
    </div>
    <button type="submit">Register</button>
}
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Darin, what if you have more complex validation rules? I find using the annotations very cumbersome and I would rather just write out the jquery even if I have a view model. – SoftwareSavant Nov 19 '12 at 14:18
  • 1
    @DmainEvent, yes data annotations are not well suited for complex validation scenarios. I would rather use FluentValidation.NET on the server to implement the complex validation scenarios and on the client leave only the strict minimum. If you need complex validation rules on the client you could write the jquery validate rules manually. – Darin Dimitrov Nov 19 '12 at 16:35
  • Darin... I need to write the jquery validation manually. And I have the logic pretty much in mind, but I can't figure out how to get it to work. Do I need to get rid of unobtrusive.validation and just use validation? How does one go about that? – SoftwareSavant Nov 19 '12 at 16:37
  • @DmainEvent, there are 2 approaches: 1. extend the jquery unobtrusive validation with custom rules (see http://stackoverflow.com/a/4747466/29407 for example) or 2. completely get rid of it and write all the rules manually. – Darin Dimitrov Nov 19 '12 at 16:47