GetUnobtrusiveValidationAttributes始终返回空集合

时间:2015-04-09 14:24:45

标签: c# asp.net-mvc-4 razor

我有一个通用编辑器div我在一起。一些字段是必需的,我想添加不显眼的验证。有一个与这些字段相关联的视图模型,但它存储在一个集合中,而这个div独立于该集合。

所以我的模型看起来像这样:

public class MyViewModel
{
    public List<GridModel> GridModels { get; set;}
}

public class GridModel
{
    [Required]
    public string GridField { get; set; }
}

我的观点如下:

<div class="EditorDiv">
    @Html.TextBox("GridField")
</div>

根据我的研究,我应该能够做到这样的事情:

@{
    var metadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(GridModel));
}
@Html.TextBox("myGridField", Html.GetUnobtrusiveValidationAttributes("GridField", metadata))

这个编译并运行得很好,但GetUnobtrusiveValidationAttributes总是返回一个空集合。我错过了什么?

2 个答案:

答案 0 :(得分:1)

我的助手也有同样的问题。

如果我有ModelName = GridModels[0].GridField 我称之为方法:

htmlHelper.GetUnobtrusiveValidationAttributes(ModelName)

它返回empty dictionary

因为我是帮手,如果我用ModelMetadata(由表达式加载)参数调用方法,它可以工作:

var ModelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData)
htmlHelper.GetUnobtrusiveValidationAttributes(ModelName, ModelMetadata )

最后返回正确的字典:)

答案 1 :(得分:0)

如果视图中的模型为@model GridModel,(并假设其位于<form>标记内),则使用@Html.TextBox("GridField")将生成正确的data-val-*属性。

html的实际输出是

<input data-val="true" data-val-required="The GridField field is required." id="GridField" name="GridField" type="text" value="">

但是,如果视图中的模型为MyViewModel,则使用@Html.TextBox("GridField")表示您尝试绑定到不存在的MyViewModel属性,因此输出将为

<input id="GridField" name="GridField" type="text" value="">

要绑定到您的模型属性,您需要for循环(或EditorTemplate类型为GridModel

@model MyViewModel
@using (Html.BeginForm())
{
    for(int i = 0; i < Model.GridModels.Count; i++)
    {
        @Html.TextBoxFor(m => m.GridModels[i].GridField)
    }
}

将生成(对于集合中的第一个GridModel

<input data-val="true" data-val-required="The GridField field is required." id="GridModels[0].GridField" name="GridModels[0].GridField" type="text" value="">

附注:你最后一段代码的问题是你获得了类的验证属性(不存在),而不是属性,它需要是

@{
    var typeMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(GridModel));
    var propertyData = typeMetadata.Properties.Where(x => x.PropertyName == "GridField").FirstOrDefault();

并且propertyData的结果将是包含2个项目的词典

{[data-val-required, The GridField field is required.]}
{[data-val, true]}

并非您在视图中需要该代码,但如果您这样做,那么使用@Html.TextBox("myGridField", propertyData)无论如何都不会有效,因为它使用this overload,您需要this overload