验证MVC4中的下拉列表,未生成data-val属性

时间:2013-11-01 17:03:37

标签: c# asp.net-mvc asp.net-mvc-4 unobtrusive-validation html.dropdownlistfor

我在MVC4的下拉列表中进行不显眼的验证时遇到了极大的困难。

我看到的主要症状是data-val属性没有在下拉元素上呈现。

根本原因是DropDownFor正在查看编辑器模板的模型,该模型上没有任何验证属性。验证在父对象属性/主模型上。我在这篇文章中使用@DarinDimitrov建议的下拉实现:https://stackoverflow.com/a/17760548/89092

是否有人知道基于模型值实现下拉框的模式,该模型值是具有选定标记的密钥对列表并且具有不引人注意的验证?

我希望能够在编辑器模板中调用Html.GetUnobtrusiveValidationAttributes(),附加属性并保留我拥有的代码 - 但对于我的生活,我无法弄清楚如何获取任何数据从它 - 我认为这是因为我在这一点上的ViewData.ModelMetadata的范围是DropDownValues类型,而不是具有装饰属性test_dd的主模型,但是如果有人知道什么谜语可以输入这个小黑盒子那会很棒。

我的模特:

...
[Required]
[UIHint("SelectListItemDD")]    
public DropDownValues test_dd { get; set; }
...

这是DropDownValues视图模型

public class DropDownValues : IDropDownValues
{
    public string SelectedValue { get; set; }
    public IEnumerable<SelectListItem> Items { get; set; }
}

我的编辑器模板视图模型

@model  DropDownValues
@{
    string initial = (ViewData.ModelMetadata).AdditionalValues["InitialValue"] as string;
}
@{if (Model != null && Model.Items != null && Model.Items.Count() > 0)
  {
    @Html.DropDownListFor(x => x.SelectedValue,
    new SelectList(Model.Items, "Value", "Text"), initial)
  }
}

2 个答案:

答案 0 :(得分:1)

我喜欢这个问题的真正答案 - 与此同时,这是我的解决方法。

即使我已经开发了一个Locale感知的必需属性,我不得不在我的模型中复制它的功能(我有一个只提供全局资源的自定义资源提供程序,所以这不适用于当前的MVC本地化方案属性: - ((()

使用我模型中的本地化消息,我手动添加了data-val属性: - ((

这是编辑器模板:

@model  DropDownValues

@{
    string initial = null;

    if (Model != null && !string.IsNullOrWhiteSpace(Model.InitialValue))
    {
        initial = Model.InitialValue;
    }

    object attrributes;
}

@{if (Model != null && Model.Items != null && Model.Items.Count() > 0)
  {
      if (Model.Required)
      {
          attrributes = new
          {
              data_val_required = Model.RequiredValidationMessage,
              data_val = "true"
          };
      }
      else
      {
          attrributes = null;
      }

    @Html.DropDownListFor(x => x.SelectedValue,
    new SelectList(Model.Items, "Value", "Text"), initial, attrributes)
  }
}

答案 1 :(得分:1)

我遇到了同样的问题并找到了解决方案。当我使用&#39;名称&#39;来调用GetUnobtrusiveValidationAttributes时参数,它没有返回任何属性。如果我添加了元数据属性,则返回属性。以下是一个示例电话:

public static MvcHtmlString DropDownListCustom<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes)
{
    var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
    var atts = html.GetUnobtrusiveValidationAttributes(metadata.PropertyName, metadata);
}

在我的情况下,&#39; atts&#39;字典现在有一个必填字段的2个值:data-val和data-val-required。我有2个必填字段,但只有一个正常工作。这是我在GetUnobtrusiveValidationAttributes调用之后添加的代码:

    if (atts != null && atts.Count > 0)
    {
        foreach (var attr in atts)
        {
            htmlAttributes.Add(attr.Key, attr.Value);
        }
    }

...然后再打电话:

    builder.AppendLine(html.DropDownList(metadata.PropertyName, selectList, htmlAttributes).ToString());

请注意,一旦调用GetUnobtrusiveValidationAttributes,如果再次尝试调用它,则什么也得不到。这就是为什么我必须在所有情况下自己添加属性。