同じ問題の解決策を探しているときにこの回答を見つけ、回避策を思いつきました。
1 つの ValidationAttribute の代わりに、2 つ用意します。
1.) ServerValidationAttribute がクラスにあり、IClientValidatable を実装しません。
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class MyCustomServerValidationAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
// remember to cast to the class type, not property type
// ... return true or false
}
}
2.) ClientValidationAttribute はフィールド/プロパティにあり、IClientValidatable を実装しますが、IsValid オーバーライドは常に true を返します。
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property,
AllowMultiple = false, Inherited = true)]
public class MyCustomClientValidationAttribute : ValidationAttribute,
IClientValidatable
{
public override bool IsValid(object value)
{
return true;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = ErrorMessage,
ValidationType = "mycustomvalidator",
};
var viewContext = (ViewContext)context;
var dependentProperty1 = viewContext.ViewData.TemplateInfo
.GetFullHtmlFieldId("DependentProperty1");
//var prefix = viewContext.ViewData.TemplateInfo.HtmlFieldPrefix;
rule.ValidationParameters.Add("dependentproperty1", dependentProperty1);
yield return rule;
}
}
クライアントで実行すると、サーバー属性は無視され、その逆も同様です。
クラスに検証属性が必要な場合は、複数のフィールドに対して検証が行われる可能性があります。クライアント検証メソッドに追加パラメーターを渡す定型コードを書きましたが、期待どおりに動作しません。私の実際のコードでは、viewContext 変数とdependentProperty1 変数をコメントアウトし、「DependentProperty1」文字列を rule.ValidationParameters.Add メソッドの 2 番目の引数に渡しただけです。何らかの理由で、正しくない HtmlFieldPrefix を取得しています。誰かがこれを助けることができるなら、コメントしてください...
とにかく、次のようなビューモデルになります。
[MyCustomServerValidation(ErrorMessage = MyCustomValidationMessage)]
public class MyCustomViewModel
{
private const string MyCustomValidationMessage = "user error!";
[Display(Name = "Email Address")]
[MyCustomClientValidation(ErrorMessage = MyCustomValidationMessage)]
public string Value { get; set; }
[HiddenInput(DisplayValue = false)]
public string DependentProperty1 { get; set; }
}
次のようなクライアント スクリプト:
/// <reference path="jquery-1.6.2.js" />
/// <reference path="jquery.validate.js" />
/// <reference path="jquery.validate.unobtrusive.js" />
$.validator.addMethod('mycustomvalidator', function (value, element, parameters) {
var dependentProperty1 = $('#' + parameters['dependentproperty1']).val();
// return true or false
});
$.validator.unobtrusive.adapters.add('mycustomvalidator', ['dependentproperty1'],
function (options) {
options.rules['mycustomvalidator'] = {
dependentproperty1: options.params['dependentproperty1']
};
options.messages['mycustomvalidator'] = options.message;
}
);
そして、このようなビュー:
@Html.EditorFor(m => m.Value)
@Html.EditorFor(m => m.DependentProperty1)
@Html.ValidationMessageFor(m => m.Value)
@Html.ValidationMessageFor(m => m)
次に、クライアントの検証を無効にしている場合は@Html.ValidationMessageFor(m => m)
、プロパティの代わりに が表示されます。