自定义DropdownlistFor无法使用jQuery.Validate()进行验证

时间:2013-12-02 00:35:39

标签: asp.net-mvc jquery-validate html-helper html-select html.dropdownlistfor

我创建了一个包含DropdownlistFor方法的自定义帮助器方法。当我选择-1。 index,其他Dropdownlists可以直接验证。另一方面,在提交表单并返回上一页之前,不会验证自定义下拉列表。这是我的自定义帮助方法和Razor中自定义DropdownlistFor的用法。


我的自定义助手:

public static MvcHtmlString MyDropdownList(this HtmlHelper htmlHelper, string name, IEnumerable<MySelectItem> list, string optionLabel, IDictionary<string, object> htmlAttributes)
{
    TagBuilder dropdown = new TagBuilder("select");
    dropdown.Attributes.Add("name", name);
    dropdown.Attributes.Add("id", name);
    StringBuilder options = new StringBuilder();

    // Make optionLabel the first item that gets rendered.
    if (optionLabel != null)
        options = options.Append("<option value='" + String.Empty + "'>" + optionLabel + "</option>");

    foreach (var item in list)
    {
        if(item.Disabled == "disabled")
            options = options.Append("<option value='" + item.Value + "' class='" + item.Class + "' disabled='" + item.Disabled + "'>" + item.Text + "</option>");
        else
            options = options.Append("<option value='" + item.Value + "' class='" + item.Class + "'>" + item.Text + "</option>");
    }
    dropdown.InnerHtml = options.ToString();
    dropdown.MergeAttributes(new RouteValueDictionary(htmlAttributes));
    return MvcHtmlString.Create(dropdown.ToString(TagRenderMode.Normal));
}


剃刀:

@Html.LabelFor(m=>m.Applicant.MeetingId)              
@Html.MyDropdownListFor(m => m.Applicant.MeetingId, 
  ViewBag.MeetingData as List<MyHelpers.MySelectItem>, 
  null, new { name = "meetingId", id = "meetingId"})                   
@Html.ValidationMessageFor(m => m.Applicant.MeetingId, null , 
  new { @class = "ValidationErrors" })


---更新我--------------------------------------- -----------------------------------

public class MySelectItem : SelectListItem
{            
    public string Class { get; set; }
    public string Disabled { get; set; }
}


public static MvcHtmlString MyDropdownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<MySelectItem> list, string optionLabel, object htmlAttributes = null)
{
    if (expression == null)
    {
        throw new ArgumentNullException("expression");
    }
    ModelMetadata metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData);
    string name = ExpressionHelper.GetExpressionText((LambdaExpression)expression);
    return MyDropdownList(htmlHelper, metadata, name, optionLabel, list, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}


private static MvcHtmlString MyDropdownList(this HtmlHelper htmlHelper, ModelMetadata metadata, string name, string optionLabel, IEnumerable<MySelectItem> list, IDictionary<string, object> htmlAttributes)
{
    string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
    if (String.IsNullOrEmpty(fullName))
    {
        throw new ArgumentException("name");
    }

    TagBuilder dropdown = new TagBuilder("select");
    dropdown.Attributes.Add("name", fullName);
    dropdown.GenerateId(fullName);
    dropdown.MergeAttributes(htmlAttributes); //dropdown.MergeAttributes(new RouteValueDictionary(htmlAttributes));
    dropdown.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata));

    StringBuilder options = new StringBuilder();

    // Make optionLabel the first item that gets rendered.
    if (optionLabel != null)
        options = options.Append("<option value='" + String.Empty + "'>" + optionLabel + "</option>");

    foreach (var item in list)
    {
        if (item.Disabled == "disabled")
            options = options.Append("<option value='" + item.Value + "' class='" + item.Class + "' disabled='" + item.Disabled + "'>" + item.Text + "</option>");
        else
            options = options.Append("<option value='" + item.Value + "' class='" + item.Class + "'>" + item.Text + "</option>");
    }
    dropdown.InnerHtml = options.ToString();
    return MvcHtmlString.Create(dropdown.ToString(TagRenderMode.Normal));
}

1 个答案:

答案 0 :(得分:2)

您的自定义DropdownListFor必须包含验证属性。你可以通过调用

来做到这一点

dropdown.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata));

这是修改后的代码

public static MvcHtmlString MyDropdownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<MySelectItem> list, string optionLabel, IDictionary<string, object> htmlAttributes = null)
{
    if (expression == null)
    {
        throw new ArgumentNullException("expression");
    }
    ModelMetadata metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData);
    string name = ExpressionHelper.GetExpressionText((LambdaExpression) expression);
    return MyDropdownList(htmlHelper, metadata, name, optionLabel, list, htmlAttributes);
}

private static MvcHtmlString MyDropdownList(this HtmlHelper htmlHelper, ModelMetadata metadata, string name, string optionLabel, IEnumerable<MySelectItem> list, IDictionary<string, object> htmlAttributes)
{
    string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
    if (String.IsNullOrEmpty(fullName))
    {
        throw new ArgumentException("name");
    }

    TagBuilder dropdown = new TagBuilder("select");
    dropdown.Attributes.Add("name", fullName);
    dropdown.GenerateId(fullName);
    dropdown.MergeAttributes(htmlAttributes);
    dropdown.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata));

    StringBuilder options = new StringBuilder();

    // Make optionLabel the first item that gets rendered.
    if (optionLabel != null)
        options = options.Append("<option value='" + String.Empty + "'>" + optionLabel + "</option>");

    foreach (var item in list)
    {
        if (item.Disabled == "disabled")
            options = options.Append("<option value='" + item.Value + "' class='" + item.Class + "' disabled='" + item.Disabled + "'>" + item.Text + "</option>");
        else
            options = options.Append("<option value='" + item.Value + "' class='" + item.Class + "'>" + item.Text + "</option>");
    }
    dropdown.InnerHtml = options.ToString();
    return MvcHtmlString.Create(dropdown.ToString(TagRenderMode.Normal));
}

另外,不要忘记视图中包含JQuery验证脚本

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

一些建议

  1. 还可以使用TagBuilder构建选项元素
  2. 您可能希望在自定义DropdownListFor
  3. 中显示当前选定的值
  4. 如果服务器中的验证失败,您可能希望添加验证失败的CSS类
  5. 最后,如果您想手动调用客户端验证,请调用

    $(selector).valid()