Итак, я проверил этот ответ of">Динамическая проверка ASP:NET MVC 4 свойства в зависимости от текущего значения другого свойства и не охватывает проблему, с которой я столкнулся.
Я использую проверку на стороне сервера. У меня есть требование, что...
Значение требуется, только если указано другое свойство
Проблема
MVC связывает каждое свойство и вызывает каждый валидатор для этого свойства по мере их связывания. Если я зависим от нескольких свойств, установленных при проверке validationContext.ObjectInstance.[MY_DEPENDENT_PROPERTY]
, есть вероятность, что эти зависимые свойства еще не привязаны.
Что мне нужно, так это атрибут проверки, который проверяет после привязки, если он вообще существует.
Итак, вот простой пример, объясняющий мою ситуацию (не предназначен для выполнения, поскольку он, скорее всего, будет в порядке, поскольку проблема связана с порядком привязки)
Моя модель
public class Address
{
[Required]
public string ResidentialAddress { get; set; }
public bool PostalIsTheSameAsResidential { get; set; }
// will only be required if PostalIsTheSameAsResidential is false.
// see the static method below and RequiredIfAttribute
[RequiredIf(typeof(Address), nameof(PostalRequiredIfNotSameAsResidential)]
public string PostalAddress { get; set; }
public static bool PostalRequiredIfNotSameAsResidential(Address model)
{
return !model.PostalIsTheSameAsResidential;
}
}
Мой валидатор
По сути, здесь происходит вызов статического метода модели, чтобы проверить, следует ли ее проверять.
public sealed class RequiredIfAttribute : RequiredAttribute
{
private readonly MethodInfo _validationMethod;
public override bool RequiresValidationContext => true;
public RequiredIfAttribute(Type type, string methodName)
{
this._validationMethod = type.GetMethod(methodName);
if (this._validationMethod == null)
{
throw new MethodAccessException($"The validation method '{methodName}' does not exist on type '{type}");
}
}
public override bool IsValid(object value)
{
throw new NotSupportedException();
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
ValidationResult result = ValidationResult.Success;
var parameters = this._validationMethod.GetParameters();
var returnType = this._validationMethod.ReturnType;
if (returnType == typeof(bool) && parameters.Length == 1 && parameters[0].ParameterType == validationContext.ObjectType)
{
if ((bool)_validationMethod.Invoke(null, new object[] { validationContext.ObjectInstance }))
{
if (!base.IsValid(value))
{
string[] memberNames;
if (validationContext.MemberName == null)
{
memberNames = null;
}
else
{
memberNames = new string[1];
memberNames[0] = validationContext.MemberName;
}
result = new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName), memberNames);
}
}
return result;
}
var expectedFuncType = typeof(Func<,>).MakeGenericType(validationContext.ObjectType, typeof(bool));
throw new MethodAccessException($"The validation method '{this._validationMethod}' does not have the correct definition. Expected '{expectedFuncType}'");
}
}
[RequiredIfFalse("PostalIsTheSameAsResidential")]
или аналогичный атрибут проверки (или вы можете легко написать свой собственный - Полное руководство по Проверка в ASP.NET MVC 3 — часть 2 - person   schedule 08.11.2016ValidationAttribute
, а неRequiredAttribute
- person   schedule 08.11.2016validationContext
методаIsValid()
содержит всю информацию о необходимых вам значениях свойств —var property = validationContext.ObjectInstance.GetType().GetProperty("PostalIsTheSameAsResidential "); var propertyValue = property.GetValue(validationContext.ObjectInstance, null);
вернет значение вашего свойстваbool
. - person   schedule 08.11.2016validationContext
. Не уверен, что вы имеете в виду, ответ на ваш первый комментарий заключается в том, что мне нужно запустить код C# при проверке? Я просто комментировал, почему вы также не реализуетеIClientValidatable
и не получаете проверку на стороне клиента, а также проверку на стороне сервера. - person   schedule 08.11.2016