Skip to content

Instantly share code, notes, and snippets.

@azborgonovo
Last active July 17, 2020 22:01
Show Gist options
  • Save azborgonovo/51366fe5d9741fcf1e1d to your computer and use it in GitHub Desktop.
Save azborgonovo/51366fe5d9741fcf1e1d to your computer and use it in GitHub Desktop.
Validation in C# with System.ComponentModel
public interface IObjectValidator<T>
{
IEnumerable<ValidationResult> Validate(T @object);
}
public bool Validate(T objeto, out ICollection<ValidationResult> results)
{
var validationResults = new List<ValidationResult>();
// Default validation
var context = new ValidationContext(objeto, serviceProvider: null, items: null);
bool selfValidationFailed = !Validator.TryValidateObject(objeto, context, validationResults, validateAllProperties: true);
// Object validators
var validators = ServiceLocator.Current.GetAllInstances<IObjectValidator<T>>();
foreach (var validator in validators)
{
var validatorResults = validator.Validate(objeto);
foreach (var item in validatorResults)
validationResults.Add(item);
}
results = validationResults;
return results.Count > 0;
}
public void Validate<T>(T item)
{
ICollection<ValidationResult> results;
if (!Validate(item, out results))
throw new ValidationErrorsException(results);
}
public class SomeEntityValidation : IObjectValidator<SomeEntity>
{
readonly ISomeRepository _repository;
public SomeEntityValidation(ISomeRepository repository)
{
_repository = repository;
}
public IEnumerable<ValidationResult> Validate(SomeEntity entity)
{
// TODO: global validation rules here
}
}
[Serializable]
public class ValidationErrorsException : Exception
{
IEnumerable<ValidationResult> ValidationResults { get; set; }
public ValidationErrorsException()
{
}
public ValidationErrorsException(IEnumerable<ValidationResult> validationResults)
{
ValidationResults = validationResults;
}
public ValidationErrorsException(string message) : base(message)
{
}
public ValidationErrorsException(string message, Exception innerException) : base(message, innerException)
{
}
protected ValidationErrorsException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
// WebAPI exception handler
public class CustomExceptionHandler : ExceptionHandler
{
public override void Handle(ExceptionHandlerContext context)
{
var exception = context.Exception as ValidationErrorsException;
if (exception != null)
{
var modelState = new ModelStateDictionary();
foreach (var validationResult in exception.ValidationResults)
{
foreach (var memberName in validationResult.MemberNames)
{
modelState.AddModelError(memberName, validationResult.ErrorMessage);
}
}
context.Result = new InvalidModelStateResult(
modelState,
true,
new DefaultContentNegotiator(),
context.Request,
new MediaTypeFormatter[] { new JsonMediaTypeFormatter() }
);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment