【问题标题】:MVC3 Validation for controls in a loop循环中控件的 MVC3 验证
【发布时间】:2012-05-31 13:54:04
【问题描述】:

在我看来,我正在使整个 html 表格可编辑。表中的每个字段都有验证。这是一些示例代码...

<tbody>
    foreach (Item item in Model.Items)
    {
        <tr>
            <td>
                @Html.TextBoxFor(x => em.Value)
                @Html.ValidationMessageFor(x => em.Value)
            </td>
        </tr>
    }
</tbody>

这在浏览器上产生了两个问题。

1)由于所有控件的name属性相同,当一个字段无效时,所有同名字段都会显示错误信息。

2) 可能也和名字有关,在验证表单时,如果第一行的控件无效,则表单无效。但所有其他行中的控件不会使表单无效(即使显示了错误消息)。

if (!$(form).valid()) {
    return false;
}

任何想法都会有所帮助。

更新:解决方案

根据 bobek 的建议,我为 TextBoxInLoopF​​or 和 ValidationMessageInLoop 创建了自定义扩展。以下是解决方案:

public static MvcHtmlString TextBoxInLoopFor<TModel, IItem, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, IItem item, object htmlAttributes)
{
    var model = item as IInLoopForModel; 
    if (model == null)
        return MvcHtmlString.Empty; 

    var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
    var fieldName = ExpressionHelper.GetExpressionText(expression);
    var name = model.Name + fieldName;

    var tag = new TagBuilder("input");
    tag.MergeAttributes(new RouteValueDictionary(htmlAttributes));
    tag.Attributes.Add("id", name);
    tag.Attributes.Add("for", name);
    tag.Attributes.Add("name", name); 
    tag.Attributes.Add("value", metadata.Model.ToString());

    // Add the validation attributes
    ModelState modelState;
    if (html.ViewData.ModelState.TryGetValue(name, out modelState))
    {
        if (modelState.Errors.Count > 0)
            tag.AddCssClass(HtmlHelper.ValidationInputCssClassName);
    }
    tag.MergeAttributes(html.GetUnobtrusiveValidationAttributes(name, metadata));

    return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
}

public static MvcHtmlString ValidationMessageInLoopFor<TModel, IItem, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, IItem item)
{
        var model = item as IInLoopForModel;
    if (model == null)
        return MvcHtmlString.Empty;

    var fieldName = ExpressionHelper.GetExpressionText(expression);
    var name = model.Name + fieldName;

    var tag = new TagBuilder("span");
    tag.Attributes.Add("class", "field-validation-valid");
    tag.Attributes.Add("data-valmsg-replace", "true");
    tag.Attributes.Add("data-valmsg-for", name);
    return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
}

【问题讨论】:

    标签: asp.net-mvc-3 validation


    【解决方案1】:

    这根本无效。用于输入的 MVC3 助手正在为每个添加一个 ID,因此在这里您将有多个具有相同 ID 的文本框 - 它在 HTML 中无效。

    您应该手动为模型上的每个属性创建一个 TextBoxFor 和 ValidationFor ,或者如果可能尝试:

    foreach (Item item in Model.Items)
        {
            <tr>
                <td>
                    @Html.TextBoxFor(x => item.Value)
                    @Html.ValidationMessageFor(x => item.Value)
                </td>
            </tr>
        }
    

    【讨论】:

    • 当时认为这是要走的路。现在调查。
    【解决方案2】:

    我建议在您的 domain.model 中使用元数据。这里有一个小例子让你了解这个过程:

    namespace yourDomain.Domain.Model
    {
        [MetadataType(typeof(fooEntityMeta))]
        public partial class fooEntity
        {
    }
    

    并从您的实体中选择值字段;使其成为必需的

    public class fooEntityMeta
        {
            [Required(ErrorMessage = "Value is required")]
            public string Value;  
           ...
        }
    


    这是一个可以帮助您完成整个过程的链接:http://msdn.microsoft.com/en-us/magazine/ee336030.aspx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-26
      相关资源
      最近更新 更多