Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save cobysy/a32a6fa87b3f8d7ff6c3 to your computer and use it in GitHub Desktop.
Save cobysy/a32a6fa87b3f8d7ff6c3 to your computer and use it in GitHub Desktop.
[AttributeUsage(AttributeTargets.Method)]
public class ValidationActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
InnerOnActionExecuting(actionContext);
var modelState = actionContext.ModelState;
if (modelState.IsValid)
{
return;
}
ErrorResource errorResource = BuildErrorResource(modelState);
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, errorResource);
}
private ErrorResource BuildErrorResource(ModelStateDictionary modelState)
{
var error = new ErrorResource
{
Message = "Your request is invalid.",
Errors = new Dictionary<string, IEnumerable<string>>()
};
foreach (KeyValuePair<string, ModelState> item in modelState)
{
IEnumerable<string> itemErrors = item.Value.Errors.Select(childItem => childItem.ErrorMessage);
error.Errors.Add(item.Key, itemErrors);
}
return error;
}
private void InnerOnActionExecuting(HttpActionContext actionContext)
{
// Retrieve the dependency scope for the current request
// (FluentValidation's FluentValidationModelValidatorProvider and ValidatorFactoryBase does not support this)
IDependencyScope scope = actionContext.Request.GetDependencyScope();
foreach (KeyValuePair<string, object> argument in actionContext.ActionArguments)
{
IValidator validator = GetScopedValidator(argument.Value.GetType(), scope);
ValidationResult result = validator.Validate(argument.Value);
foreach (ValidationFailure error in result.Errors)
{
Trace.WriteLine(error.PropertyName);
actionContext.ModelState.Add(error.PropertyName,
new ModelState
{
Value = new ValueProviderResult(error.AttemptedValue, error.AttemptedValue?.ToString() ?? string.Empty, CultureInfo.CurrentCulture)
});
actionContext.ModelState.AddModelError(error.PropertyName, error.ErrorMessage);
}
}
}
private IValidator GetScopedValidator(Type type, IDependencyScope scope)
{
Type validatorType = typeof (IValidator<>).MakeGenericType(type);
IValidator validator = scope.GetService(validatorType) as IValidator;
return validator;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment