MVC3:客户端验证

时间:2011-09-14 05:33:25

标签: jquery asp.net-mvc-3

我有一个迷你表单,包含所有选择框和复选框列表。

我已经在viewmodel中设置了数据注释。因此,如果我提交表单(没有启用javascript),ModelState.IsValid的工作方式就像它应该的那样。

但在客户端验证中,我遇到了问题。我有不引人注意的jquery验证,但是当我做$("#form").valid()时,它总是返回true。

我不确定如何自定义并检查条件。例如,我有一个复选框列表,默认情况下没有选中任何内容。因此,如果未选中任何内容,.valid()应返回false。此外,其中2个下拉列表中有一个“请选择”选项,但jquery仍然返回有效。服务器端ModelState.IsValid适用于这两种情况。

以下是一个例子:

@using (Html.BeginForm("index", "home", FormMethod.Post, new { @id = "miniForm" })) {
@Html.ValidationSummary(true)
@Html.AntiForgeryToken()

<div>
    @Html.LabelFor(m => m.NinjaType)
    @Html.DropDownListFor(m => m.NinjaType, Model.NinjaTypeList) // First value is '0'. Rest of the list is of type STRING
</div>

/// following is the rendered html code as i created a helper for it which i've omitted in this example
<ul>
    <li><input type="checkbox" id="poo1" name="pie" value="one" />one</li>
    <li><input type="checkbox" id="poo2" name="pie" value="two" />two</li>
    <li><input type="checkbox" id="poo3" name="pie" value="three" />three</li>
</ul>

<input type="submit" id="submitButton" />
}

如果有帮助,这是POST控制器操作:

public ActionResult Index(SuperDooperNinjaViewModel m)
{
    if (this.ModelState.IsValid)
        return Redirect("win");
    else 
        return Redirect("fail");
}

我在想{我在$('#submitButton').click();做老式的方式,但我觉得可能有更好的方法来做到这一点。我想到的另一种方法是将其转换为Ajax形式。因此,在服务器端响应中,我返回Redirect("fail");

,而不是JsonResult

总而言之,验证此表单的最佳途径是什么?

  • NinjaType的值必须为'0'
  • 必须至少选中一个复选框。

提前致谢

更新

视图模型:

public class SuperDooperViewModel
{
    [Required]
    public string NinjaType {get;set;}
    public IEnumerable<SelectItemList> { get;set; }

    [Required]
    public string[] pie {get;set;} // checkbox
    public IEnumerable<string> PieList { get;set; } // list of values for checkbox
}

在jquery中,我正在测试它:

$("#submitButton").click(function(e) {
    e.preventDefault();
    if ($("#miniForm").valid())
         alert("valid");
    else
         alert("fail");
});

2 个答案:

答案 0 :(得分:1)

对于下拉列表,这很简单:

public class SuperDooperNinjaViewModel
{
    [Required]
    public string NinjaType { get; set; }

    public SelectList NinjaTypeList { get; set; }
}

并在视图中:

@Html.DropDownListFor(
    m => m.NinjaType, 
    Model.NinjaTypeList,
    "Please Select"
)

现在,对于复选框,您谈到了生成它们的一些HTML帮助程序,但是我看不到这个帮助程序发出任何用于不显眼验证的HTML5 data-*属性。

答案 1 :(得分:0)

我不确定这是否是最好的方法,但是现在,我已经抛出了checkboxlist扩展名,只是手动完成了这个:

@foreach(var nt in Model.NinjaTypeList)
{
    <li>@Html.CheckBox("pie", new { @id = nt })</li>
}
@Html.HiddenFor(m => m.NinjaType)

在jquery中,我将一个事件附加到复选框:

$('input[name=pie]').click(function(){
    var pie = "";
    $('input[name=pie]').each(function(i) {
       if ($(this).is(':checked'))
           pie += $(this).val() + ';';
    });
    $("#NinjaType").val(pie);
});

在我的控制器中:

public ActionResult Index(SuperDooperViewModel m, string[] pie)
{
    /// I've add the following as a work around:
    if (string.IsNullOrEmpty(m.NinjaType) // no reason it should be, but it's a sort of failsafe
    {
         if(pie.Any())
              m.NinjaType = string.Join(";", pie.Where(w => w != "false"));
    }

    // rest of the controller here
}

这基本上可以满足我的需要,但对我来说这似乎是一项工作。任何改进都将受到赞赏。