Ben*_*son 8 c# asp.net-mvc unobtrusive-validation asp.net-mvc-3
我试图解决这样一个事实:当他们编写asp.net MVC 3时,他们忘记包含代码来添加不显眼的验证属性到选择列表,他们的"修复"就是将它包含在MVC 4中,这不是血腥的使用MVC 3的任何人.
我建议的解决方法是使用Html.GetUnobtrusiveValidationAttributes()
自己添加它们,就像任何其他自定义属性一样,但我无法确定调用方法的正确语法.有2个重载,一个接受一个字符串,另一个接受一个字符串和一个ModelMetaData类.我理解元数据参数,我认为我只是传入ViewData.ModelMetadata
但字符串应该是什么?MSDN文档说它是"指定的HTML名称属性",这对我来说毫无意义.HTML名称属性是什么?选择清单?为什么它需要它以及它如何帮助它知道我的模型上我想要验证的属性?查看使用示例,他们似乎都传递了我的模型上属性的名称,我想要验证属性,这是有道理的.不幸的是,无论我传递什么,我都无法让方法返回任何空集合.
我的模型类叫做Event,我的属性叫做EventTypeID.我使用稍微不同的viewmodel类作为视图的基础,因为我需要显示事件列表,并且还允许在同一视图上输入新事件,因此我有一个简单的viewmodel类,如下所示:
public class EventViewModel
{
public Model.Event NewEvent { get; set; }
public IEnumerable<Model.Event> Events { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
下拉列表映射到属性,如:@Html.DropDownListFor(model => model.NewEvent.EventTypeID
我将作为字符串传递给Html.GetUnobtrusiveValidationAttributes(string)
或Html.GetUnobtrusiveValidationAttributes(string, ModelMetadata)
获取此属性的属性.我试过了:
Html.GetUnobtrusiveValidationAttributes("EventTypeID")
Html.GetUnobtrusiveValidationAttributes("EventTypeID",ViewData.ModelMetadata)
Html.GetUnobtrusiveValidationAttributes("NewEvent.EventTypeID")
Html.GetUnobtrusiveValidationAttributes("NewEvent.EventTypeID",ModelMetadata)
Run Code Online (Sandbox Code Playgroud)
他们都返回一个空集合.
我知道我的模型是正确的,因为如果我将调用更改Html.DropDownListFor
为Html.TextBoxFor
然后验证"正常工作",除了将验证属性添加到我的模型类之外,我不需要做任何事情.
编辑:
刚尝试关闭客户端验证,验证在所有选择列表的服务器端都很好.
Moe*_*eri 15
对于那些仍在寻找答案的人来说,这对我有用:
public static IDictionary<string, object> UnobtrusiveValidationAttributesFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> propertyExpression)
{
var propertyName = html.NameFor(propertyExpression).ToString();
var metadata = ModelMetadata.FromLambdaExpression(propertyExpression, html.ViewData);
var attributes = html.GetUnobtrusiveValidationAttributes(propertyName, metadata);
return attributes;
}
Run Code Online (Sandbox Code Playgroud)
请注意,我使用的是.Net MVC 4,您在MVC 3中没有html.NameFor方法.但是,我相信这可以通过以下方法在MVC 3中完成:
var propertyName = ExpressionHelper.GetExpressionText(propertyExpression);
Run Code Online (Sandbox Code Playgroud)
您可以内联使用
选择元素示例
<select name="@Html.NameFor(m=> m.MyProperty)"
id="@Html.IdFor(m=> m.MyProperty)"
@Html.Raw(string.Join(" ", Html.GetUnobtrusiveValidationAttributes(Html.NameFor(m => m.MyProperty).ToString()).Select(x => x.Key.ToString() + "=\"" + x.Value + "\"")))
>
Run Code Online (Sandbox Code Playgroud)
这是我发布的答案的链接,显示了我编写的为下拉列表提供不显眼的验证的 HtmlHelper: MVC 3 dropdownlist验证不适用于复杂视图模型
\n\n更新
\n\n您是否正在尝试获取 HtmlHelper 中的属性,或者在视图中内嵌属性?
\n\n假设您正在尝试获取视图中的属性,这就是问题所在。
\n\n首先,您需要了解 ModelMetadata 并不代表整个模型中可用的单个对象。相反,它表示特定元素的元数据,无论是您的模型还是模型中的任何属性。更好的描述性名称是ObjectMetadata
,因为 ModelMetadata 是指定对象的元数据,无论是模型、嵌套模型还是特定属性。
视图中的ModelMetadata只是顶层模型的元数据。您必须获取下拉列表绑定到的属性的 ModelMetadata。如果您使用助手,那么助手会自然而然地传递正确的 ModelMetadata。如果您使用您的视图,则需要进行一些练习才能获得正确的 ModelMetadata,例如,请参阅我的答案: Validating and edit a \xe2\x80\x9cChangeable\xe2\x80\x9d/optical type in Asp.net MVC 3
\n