Client-side validation not working in ASP.NET MVC5

2019-02-05 14:56发布

Running Visual Studio 2013, I created a new ASP.NET MVC (5) project, with Bootstrap.

However, I'm unable to get unobtrusive client-side validation working.

The model has [Required] attributes on the relevant properties and the view has ValidationMessageFor... tags for each field in the form.

However, submitting the form causes the form to postback to server before validation messages appear.

Using NuGet, I've installed jquery.validate and jquery.validate.unobtrusive and added them to the jquery bundle in App_Start.

Yet it continues to stubbornly post back to server. F12 dev tools shows no JS errors/warnings.

Has anybody else come across this issue (can't see anything in SO relating to MVC 5 specifically) and do you have any ideas?

10条回答
Rolldiameter
2楼-- · 2019-02-05 15:01

Have you verified <add key="ClientValidationEnabled" value="true" /> in web.config?

Otherwise, this provides a good overview: ASP.NET MVC 3: Required steps for unobtrusive client-side validation of dynamic/AJAX content. Also valid for MVC5.

查看更多
干净又极端
3楼-- · 2019-02-05 15:02

I am providing this answer for future readers.I was dealing with the same issue and found the problem is with the sequence of the render scripts. Make Sure

@Scripts.Render("~/bundles/jquery")    

is before

@Scripts.Render("~/bundles/jqueryval")

in _layout.cshtml . The layout bottom part should look like follow.

@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryval")
@Scripts.Render("~/bundles/bootstrap")
查看更多
来,给爷笑一个
4楼-- · 2019-02-05 15:09

I was having the same issue when I was playing with my first MVC project. The issue was at the end that I didn't include the input elements to the form element. Yes, very stupid. Make sure you create the form, for instance :

@using (Html.BeginForm())
{
    @Html.EditorFor(model => model.FieldA)
    @Html.ValidationMessageFor(model => model.FieldA)

    @Html.EditorFor(model => model.FieldB)
    @Html.ValidationMessageFor(model => model.FieldB)

}
查看更多
beautiful°
5楼-- · 2019-02-05 15:10

I think that @Html.ValidationMessageFor is missing from the template. I do get the errors, but not the messages.

查看更多
beautiful°
6楼-- · 2019-02-05 15:14

I know this is a little late to the game but this does add more to validation and I found it to be very helpful. Sometimes conflicting javascript/jQuery Plugin/API references (eg:searchMeme.js) that reference other jquery versions can cause problems so I create unique bundles for account login actions. These are the steps I would take:

1. Create a separate layout ~/Views/Shared/_AccountLayout.cshtml for AccountController.cs.

2. Create new ~/Account/_ViewStart.csthml with:

@{
    Layout = "~/Views/Shared/_AccountLayout.cshtml";
}

3. Create two bundles for css & js in BundleConfig.cs for AccountController:

   bundles.Add(new StyleBundle("~/Content/accountcss").Include(
                "~/Content/site.css",
                "~/Content/bootstrap.css",
                "~/Content/font-awesome.css")); /*if using font-awesome */

   bundles.Add(new ScriptBundle("~/bundles/accountjs").Include(
                "~/Scripts/jquery-1.10.2.js",
                "~/Scripts/jquery.validate.js",
                "~/Scripts/jquery.validate.unobtrusive.js",
                "~/Scripts/bootstrap.js"));//must be after jquery validate

4. Reference the bundles in both ends of head & body in _AccountLayout.cshtml as such:

        <title>@ViewBag.Title</title>
        <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
        <meta name="viewport" content="width=device-width" />
         @Styles.Render("~/Content/accountcss")
        @Scripts.Render("~/bundles/modernizr")
        @this.RenderSection("MetaContent", false)
        @this.RenderSection("Styles", false)
        </head>

        @Scripts.Render("~/bundles/accountjs")
        @this.RenderSection("Scripts", false)
        </body>

*NOTE: Make sure bootstrap is after jqueryval in bundle

5. Make sure you have @Html.ValidationMessageFor for each input field within ~/Account/Login.cshtml, ~/Account/Register.cshtml, etc... respectively.

<div class="form-group">
       @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })
          <div class="col-md-10">
               @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
               @Html.ValidationMessageFor(m => m.UserName, "", new { @class = "text-danger" })
          </div>
</div>

6. Use DataAnnotations to create additional custom validation errors [RegularExpression(@"^([\w]{2,20})@?([\w]{2,20}).?[a-zA-Z]{2,3}$", ErrorMessage="")]:

[Required(ErrorMessage = "*Username is required."), RegularExpression(@"^[\w+]{3,10}\s?([\w+]{3,15})$", ErrorMessage = "*Username can only be Alphanumeric"),StringLength(25, ErrorMessage = "The {0} must be at least {2} characters long and no bigger than {1} characters.", MinimumLength = 5)]
public string UserName { get; set; }

7. (optional) Lastly, if you changed the DataAnotation for Password then you MUST also change the Password Policy in ~/App_Start/IdentityConfig.cs as such:

manager.PasswordValidator = new PasswordValidator
{
    RequiredLength = 6,
    RequireNonLetterOrDigit = false,
    RequireDigit = true,
    RequireLowercase = true,
    RequireUppercase = true,
};

8. (optional) Also, check out this article on Roles etc..

查看更多
你好瞎i
7楼-- · 2019-02-05 15:21

Since tour using MVC instead of adding to every edit view, you could add in the view/shared folder at _Layout.cshtml.

just add

@Scripts.Render("~/bundles/jqueryval")

at the bottom of _Layout.cshtml, on top of

@Scripts.Render("~/bundles/bootstrap") @Scripts.Render("~/bundles/jqueryval")

in this case the script will effect every page that uses that layout.

查看更多
登录 后发表回答