次の(簡略化された)ビューモデルがあります:
public class RegisterModel
{
public string UserName { get; set; }
[MustExistIf("SomeProperty", "some value", "SomeOtherProperty", ErrorMessage = "You have to select something")]
public string LastName { get; set; }
public AddressModel Address { get; set; }
}
public class AddressModel
{
public string Street { get; set; }
public string House { get; set; }
}
そして私はカスタムバリデーターを持っています
public class MustExistIfAttribute : ValidationAttribute, IClientValidatable
{
private string _masterName { get; set; }
private object _masterValue { get; set; }
private string _dependantName { get; set; }
public MustExistIfAttribute(string masterName, object masterValue, string dependantName)
{
this._masterName = masterName;
this._masterValue = masterValue;
this._dependantName = dependantName;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// get value of master property
var masValue = _getValue(validationContext.ObjectInstance, _masterName);
// get value of property whch depends on master property
var depValue = _getValue(validationContext.ObjectInstance, _dependantName);
if (masValue.Equals(_masterValue)) // if value in request is equal to value in specified in data annotation
{
if (depValue == null) // if dependant value does not exist
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
}
return ValidationResult.Success;
}
public override bool IsValid(object value)
{
return base.IsValid(value);
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var modelClientValidationRule = new ModelClientValidationRule
{
ValidationType = "mustexistif",
ErrorMessage = FormatErrorMessage(metadata.DisplayName)
};
modelClientValidationRule.ValidationParameters.Add("mastername", this._masterName);
modelClientValidationRule.ValidationParameters.Add("mastervalue", this._masterValue);
modelClientValidationRule.ValidationParameters.Add("dependantname", this._dependantName);
yield return modelClientValidationRule;
}
private static object _getValue(object objectInstance, string propertyName)
{
...
}
}
次の JavaScript があります (mustexitif メソッドで false を返すのは無視してください - これはテスト目的のためだけです)
(function () {
jQuery.validator.addMethod('mustexistif', function (value, element, params) {
var masterName = params['mastername'];
var masterValue = params['mastervalue'];
var dependantName = params['dependantname'];
return false;
});
var setValidationValues = function (options, ruleName, value) {
options.rules[ruleName] = value;
if (options.message) {
options.messages[ruleName] = options.message;
}
};
var $Unob = $.validator.unobtrusive;
$Unob.adapters.add("mustexistif", ["mastername", "mastervalue", "dependantname"], function (options) {
var value = {
mastername: options.params.mastername,
mastervalue: options.params.mastervalue,
dependantname: options.params.dependantname
};
setValidationValues(options, "mustexistif", value);
});
})();
RegisterModel クラスの LastName プロパティを MustExistIf アノテーションで装飾すると、期待どおりに動作します (提供されたコードのように)。しかし、私が本当に望んでいるのは、RegisterModel の複雑な Address プロパティを MustExistIf アノテーションで装飾することです。問題は、私がそうすると、目立たないアダプターが登録されないことです(それを行うjavascriptはトリガーされません)。そのため、単純なプロパティと複雑なプロパティを装飾すると違いがあります。私のソリューションでは、 Address クラスのプロパティを装飾することはできません (参考までに、私はそれを試してみましたが、検証も正常に機能しています)。私が意図したことを達成する方法はありますか?何か不足していますか?解決策はモデルレベルで検証することですか? しかし、クライアント側の検証を行うことは可能ですか?