使用 jQuery 进行 MVC 手动表单验证始终返回 True

Posted

技术标签:

【中文标题】使用 jQuery 进行 MVC 手动表单验证始终返回 True【英文标题】:MVC Manual Form Validation with jQuery Always Returns True 【发布时间】:2013-07-19 19:26:41 【问题描述】:

在我的 MVC 4 项目中通过 ajax 请求提交表单时,我一直很难让不显眼的验证工作。作为参考,本主题中的人正在做我正在做的几乎相同的事情:

Manual form validation in MVC 3 and JQuery

我完成了那里所做的事情,但我仍然无法让它发挥作用。问题是当我执行 $("#Form").valid() 时,它总是返回 true,即使我发送请求,模型也是无效的。我在我的包中设置了适当的脚本,但我无法让表单正确验证客户端。我怎样才能使它正确验证?我认为一旦设置了数据注释,它就“应该可以工作”,但这里显然不是这样。

此外,这个特殊的表单也可以通过 jQuery 在 Kendo UI 窗口中从局部视图中加载。查看这篇文章的答案后:Asp MVC unobtrusive Client Validation always returning true 使用表单 id 作为选择器,.valid() 仍然返回 true,但类名为 false。但是,guid 学期 id 返回 true。

我的代码如下:

型号

public class Class

  public Class()
  
    ClassId = Guid.NewGuid();
  

  [Key]
  public Guid ClassId  get; set; 

  [Display(Name = "Class Name")]
  [Required(ErrorMessage = "A Class Name is required.")]
  public string ClassName  get; set; 

  public int UserId  get; set; 

  [Display(Name = "Term Type")]
  [Required(ErrorMessage = "The Term Type is required.")]
  public Guid SemesterId  get; set; 

  [ForeignKey("SemesterId")]
  public virtual Semester Semester  get; set; 

  [Display(Name = "Class Year")]
  public int Year  get; set; 

  [Display(Name = "Has Weighted Grades?")]
  public bool HasWeightedGrades  get; set; 

  public virtual List<Grade> Grades  get; set; 

表格

@using (html.BeginForm("AddClass", "", FormMethod.Post, new  name = "AddNewClassForm", id = "AddNewClassForm" ))

  <div>
    <div>@Html.LabelFor(m => m.ClassName)</div>
    <div>
      @Html.TextBoxFor(m => m.ClassName, new  @class = "input-xlarge" )
      @Html.ValidationMessageFor(m => m.ClassName)
    </div>
    <div>@Html.LabelFor(m => m.SemesterId)</div>
    <div>
      @Html.DropDownList("SemesterId", null, "-- Select a Term Type --", new  @class = "input-xlarge" )
      @Html.ValidationMessageFor(m => m.SemesterId)
    </div>
  </div>


<div>
  <button id="AddClassButton" class="btn btn-primary" type="submit"><i class="icon-plus icon-white"></i> Add Class</button>
  <button id="CancelAddClassButton" class="btn btn-danger" type="submit"><i class="icon-ban-circle icon-white"></i> Cancel</button>
</div>

jQuery 事件

//================================================================================================================================
// AddClassButton: Click event handlers.
//================================================================================================================================
$('#AddClassButton').unbind('click').bind('click', function (e) 
  $.validator.unobtrusive.parse($('#AddClassWindow'));
  var val = $("#AddNewClassForm").validate();
  val.showErrors();
  alert("Is the form valid? " + val.valid());  //Always returns true

  alert("Is Class Name Valid? " + $("#ClassName").valid());  //Still returns true
  alert("Is Semester Id Valid? " + $("#SemesterId").valid());  //Still returns true

  e.preventDefault(); // Prevent this from doing default (possibly submit form).
  e.stopPropagation(); // Prevent infinite loop.
);

捆绑

bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                      "~/Scripts/jquery.unobtrusive*",
                      "~/Scripts/jquery.validate*"));

//Ignoring these so only the min.js versions get rendered
bundles.IgnoreList.Ignore("jquery.validate.js");
bundles.IgnoreList.Ignore("jquery.validate.unobtrusive.js");
bundles.IgnoreList.Ignore("jquery.unobtrusive-ajax.js");

控制器动作

[Authorize]
public ActionResult AddClass()

  var userName = User.Identity.Name;
  var userProfile = db.UserProfiles.SingleOrDefault(x => x.UserName == userName);

  InitializeSemesters();
  InitializeYears();

  return PartialView(new Class()  UserId = userProfile.UserId, Year = DateTime.Now.Year );

【问题讨论】:

显然您发布的代码与您使用的代码不同。您发布的课程中没有 UserId,但您在剃刀代码中引用了它。如果您需要帮助,您必须发布有问题的完全相同的代码。如果它太大,您需要简化代码并生成最简单的 WORKING 代码集来说明问题。 我已更新代码并删除了 UserId 引用。它在模型中,但尚未经过验证。唯一要验证的字段是列出的字段。如果我将它传递回控制器,它会在服务器上正确验证,而不是在客户端。 这里的问题是你的代码中有很多其他的东西,当你测试时,你也在测试其他的东西。其他东西可能是问题的一部分。您需要给我们一个最完整的工作示例来说明问题。我的意思是你已经验证了你给我们的代码中存在问题。 模型中没有其他字段正在验证中。我已经确认我发布的内容重现了相同的错误。模型中不应该有任何其他东西会破坏这一点,因为它只是一个实体模型。如果我使用 jQuery 验证插件,它可以正常工作,但我认为不需要这样做。我更新了代码以显示绑定到视图的完整模型。 我还添加了控制器方法。我不确定将其作为部分视图返回是否是问题的一部分。 【参考方案1】:

您必须将以下脚本添加到您的 _Layout 或视图“jquery.unobtrusive-ajax.js” “jquery.validate.js” “jquery.validate.unobtrusive.js”

【讨论】:

【参考方案2】:

如果

alert("Is the form valid? " + val.valid());  //Always returns true

怎么样

alert("Is the form valid? " + $("#AddNewClassForm").valid());  // ???

这对我有用...

【讨论】:

【参考方案3】:

您需要在要验证的表单上调用.valid(),而不是在.validate() 方法的结果上。

与许多 jQuery 方法不同,.validate() 不适合链接,因为它返回类型为 Validator 的对象而不是原始 jQuery 对象(请参阅:http://jqueryvalidation.org/validate/)

【讨论】:

【参考方案4】:

这个扩展对我有用:

$(document).ready(function () 
    jQuery.noConflict();

    // if the form is in a dialog box 
    var form = $('#formCreateRequest');
    form
        .removeData('validator')
        .removeData('nobtrusiveValidation');
    $.validator.unobtrusive.parse(form); // 

    $.fn.extend(
        // form validation 
        isValid: function () 
            var self = $(this);
            $.validator.unobtrusive.parse(self);
            return self.data('unobtrusiveValidation').validate();
         // 
    );
);

使用:

if ($('#formId').isValid()) 
    ...
 else 
    ...

【讨论】:

以上是关于使用 jQuery 进行 MVC 手动表单验证始终返回 True的主要内容,如果未能解决你的问题,请参考以下文章

如何在 MVC 4 中使用 jquery 验证表单的隐藏输入字段?

让 MVC 4 验证 jquery 手风琴表单的所有部分

使用 jQuery 手动触发表单验证

MVC jquery表单验证 和 jquery_Validate表单验证

如何在 ASP.NET MVC 中手动设置用户角色?

mvc3 + jQuery 验证:如何捕获错误或正常事件