在我的视图中,我正在制作整个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的建议,我为TextBoxInLoopFor和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));
}
答案 0 :(得分:1)
这根本无效。用于输入的MVC3帮助器正在为每个添加一个ID,所以在这里你将有多个具有相同ID的文本框 - 它在HTML中无效。
您应该手动为模型上的每个属性创建TextBoxFor和Validation,或者如果可以的话尝试:
foreach (Item item in Model.Items)
{
<tr>
<td>
@Html.TextBoxFor(x => item.Value)
@Html.ValidationMessageFor(x => item.Value)
</td>
</tr>
}
答案 1 :(得分:0)
我建议您在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