简体   繁体   English

Html.TextBoxFor / Html.TextAreaFor和Html.EditorFor(与[DataType(DataType.MultilineText)])之间的客户端验证差异

[英]Client-side validation difference between Html.TextBoxFor/Html.TextAreaFor and Html.EditorFor (with [DataType(DataType.MultilineText)])

I am using client-side validation (unobtrusive) in ASP.NET MVC 3/Razor and I got it to work on a <textarea> by using Html.EditorFor and specifying DataType.MultilineText, but should not Html.TextAreaFor also have client-side validation? 我在ASP.NET MVC 3 / Razor中使用客户端验证(不引人注意)我通过使用Html.EditorFor并指定DataType.MultilineText让它在<textarea>上工作,但不应该Html.TextAreaFor也有客户端 -边验证?

[Required(ErrorMessage = "Foo")]
public string Message { get; set; }

// Does add client-side validation
@Html.TextBoxFor(m => m.Message)

// Does NOT add client-side validation
@Html.TextAreaFor(m => m.Message)

[Required(ErrorMessage = "Foo")]
[DataType(DataType.MultilineText)]
public string Message { get; set; }

// Does add client-side validation (and multiline)
@Html.EditorFor(m => m.Message)

// Does NOT add client-side validation
@Html.TextAreaFor(m => m.Message)

<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />

Your example above works fine for me. 你上面的例子对我来说很好。 I wonder - was this a precise example, or was it simplified from a real world problem? 我想知道 - 这是一个精确的例子,还是从现实世界的问题中简化了? I have found this exact behavior when using a model with nested properties. 在使用具有嵌套属性的模型时,我发现了这种确切的行为。

So, for example, if I change your model to look like this: 因此,例如,如果我将模型更改为如下所示:

public class MyModelObject
{
    [Required(ErrorMessage = "Foo")]
    [DataType(DataType.MultilineText)]
    public string Message { get; set; }
}

public class MyModel
{
    public MyModelObject MyObject { get; set; }
}

Then I reproduce the exact problem you mentioned. 然后我重现你提到的确切问题。

@Html.EditorFor(x => x.MyObject.Message)

generates the jquery validation attributes as expected: 按预期生成jquery验证属性:

<textarea class="text-box multi-line input-validation-error" data-val="true" data-val-required="Foo" id="MyObject_Message" name="MyObject.Message"></textarea>

But, this: 但是这个:

@Html.TextAreaFor(x => x.MyObject.Message)

Does not: 才不是:

<textarea cols="20" id="MyObject_Message" name="MyObject.Message" rows="2"></textarea>

If this does in fact describe your issue, it looks like this has been reported as a bug: http://aspnet.codeplex.com/workitem/8576 如果这实际上描述了您的问题,看起来这已经被报告为一个错误: http//aspnet.codeplex.com/workitem/8576

As obliojoe suggested in his answer, this bug appears when the expression is more complex than a simple property reference. 正如obliojoe在他的回答中所建议的,当表达式比简单的属性引用更复杂时,会出现此错误。

I have implemented replacement helpers that work around this problem. 我已经实现了解决此问题的替换助手。 The trick is to obtain correct model metadata, pass it to HtmlHelper.GetUnobtrusiveValidationAttributes() and then pass the received attributes to the original TextAreaFor() helper: 诀窍是获取正确的模型元数据,将其传递给HtmlHelper.GetUnobtrusiveValidationAttributes() ,然后将收到的属性传递给原始TextAreaFor()帮助器:

public static MvcHtmlString TextAreaWithValidationFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
{
    var modelMetadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
    var name = ExpressionHelper.GetExpressionText(expression);
    IDictionary<string, object> validationAttributes = helper.GetUnobtrusiveValidationAttributes(name, modelMetadata);
    return TextAreaExtensions.TextAreaFor(helper, expression, validationAttributes);
}

I attached a more developed version (which provides all TextAreaFor overloads, including those with htmlAttributes ) of this code to the bug reported on CodePlex . 我将此代码的更htmlAttributes版本(提供所有TextAreaFor重载,包括那些带有htmlAttributeshtmlAttributesCodePlex上报告错误

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM