private static void ValidateAgainstTypeIf( object model, IServiceProvider serviceProvider, IDictionary <object, object> items, ModelErrorDictionary modelErrors, PropertyInfo pi, ValidateAgainstTypeIfAttribute attr) { var targetProperty = model.GetType().GetProperties().First(pi2 => pi2.Name == attr.TargetPropertyName); var targetPropertyValue = targetProperty.GetValue(model); if (targetPropertyValue != null && targetPropertyValue.Equals(attr.TargetPropertyValue)) { ValidateAgainstType(model, serviceProvider, items, modelErrors, pi, attr); } }
private static void ValidateAgainstType( object model, IServiceProvider serviceProvider, IDictionary <object, object> items, ModelErrorDictionary modelErrors, PropertyInfo pi, IValidateAgainstType attr) { var propertyModelValue = pi.GetValue(model); var propertyModel = propertyModelValue as IDictionary <string, object>; if (propertyModel == null) { var propertyEnumerableModel = propertyModelValue as IEnumerable <object>; if (propertyEnumerableModel == null) { // Everything is fine. RequiredAttribute should handle validation here if not. return; } else { ValidateEnumerableElements(model, serviceProvider, items, modelErrors, pi); return; } } #region Instantiate an object of the target type so we can validate it var propertyModelPropertiesByName = propertyModel.ToDictionary( kvp => kvp.Key, kvp => kvp.Value, attr.IgnoreCase ? StringComparer.InvariantCultureIgnoreCase : StringComparer.InvariantCulture); var retypedPropertyModel = Activator.CreateInstance(attr.Type); attr.Type.GetProperties().ForEach(retypedProperty => { if (propertyModelPropertiesByName.TryGetValue(retypedProperty.Name, out object value)) { retypedProperty.SetValue(retypedPropertyModel, value); } }); #endregion var retypedValidationResult = IsValid(retypedPropertyModel, serviceProvider, items); modelErrors.Add(retypedValidationResult.modelErrors, pi.Name); }
private static void ValidateEnumerableElements( object model, IServiceProvider serviceProvider, IDictionary <object, object> items, ModelErrorDictionary modelErrors, PropertyInfo pi) { var enumerableModelErrors = new ModelErrorDictionary(); var enumerableValue = (IEnumerable)pi.GetValue(model); enumerableValue.Cast <object>().ForEach((elementModel, index) => { var elementValidationResult = IsValid(elementModel, serviceProvider, items); enumerableModelErrors.Add(elementValidationResult.modelErrors, index); }); modelErrors.Add(enumerableModelErrors, pi.Name); }
private void Add(ModelErrorDictionary other, string memberName, bool isIndex) { memberName = ResolveMemberName(memberName, isIndex); if (other.NonMemberErrors.Any()) { if (string.IsNullOrEmpty(memberName)) { NonMemberErrors = NonMemberErrors.Concat(other.NonMemberErrors); } else { if (!TryGetValue(memberName, out IEnumerable <string> memberErrors)) { memberErrors = Enumerable.Empty <string>(); } this[memberName] = memberErrors.Concat(other.NonMemberErrors); } } if (other.SelectMany(kvp => kvp.Value).Any()) { foreach (var kvp in other) { if (string.IsNullOrEmpty(memberName)) { this[kvp.Key] = kvp.Value; } else { var memberPath = memberName; if (!IsMemberPathPartIndex(kvp.Key.Split('.').First())) { memberPath += "."; } memberPath += kvp.Key; this[memberPath] = kvp.Value; } } } }
public static void AddTypeExpected(this ModelErrorDictionary modelErrorDictionary, string memberName, string typeDescriptor) => modelErrorDictionary.Add($"Expected {memberName} to be of type ${typeDescriptor}", memberName);
public static void AddUriExpected(this ModelErrorDictionary modelErrorDictionary, string memberName) => modelErrorDictionary.AddTypeExpected(memberName, "uri");
public static void AddIntegerExpected(this ModelErrorDictionary modelErrorDictionary, string memberName) => modelErrorDictionary.AddTypeExpected(memberName, "integer");
public static void AddOutOfRange(this ModelErrorDictionary modelErrorDictionary, string memberName) => modelErrorDictionary.Add($"{memberName} was out of range of the allowed values", memberName);
public static void AddRequired(this ModelErrorDictionary modelErrorDictionary, string memberName) => modelErrorDictionary.Add($"{memberName} is required", memberName);
public void Add(ModelErrorDictionary other, int index) => Add(other, index.ToString(), true);
public void Add(ModelErrorDictionary other, string memberName = null) => Add(other, memberName, false);
public ClientModelValidationException(ModelErrorDictionary modelErrors) { ModelErrors = modelErrors; }
public ClientModelValidationException(string error, string member) { ModelErrors = new ModelErrorDictionary(error, member); }