Monthly Archives: October 2019

Manual Validation in A Mediatr RequestHandler without Exceptions

This is the second post in a 2 post series:

  1. Validation without Exceptions using a MediatR Pipeline Behavior; and
  2. Manual Validation in A Mediatr RequestHandler without Exceptions

In my last post, I covered a scenario of using a Mediatr Pipeline Behavior to perform validation of a command object in such a way that no exception is thrown in the event of a validation failure. Today, I’m going to cover another strategy which involves manual validation in the Business Layer, rather than handing it off to the framework (as described in that previous post).

There may be times where you need to perform manual validation in the business layer, for one reason or another. Perhaps some code needs to run before the validation is performed and this may not be something which can happen if the validation happens automatically in the Mediatr pipeline. In such a case, we are faced with the same challenge as in my previous post; how do we bubble a validation failure up to the View, without just doing the throw/catch exception thing?

The solution which I’m putting forward in this post uses a Functional Programming construct known as a Discriminated Union. But we’ll get to that in time. First I’ll set out the scenario. I’ll try to keep it simple, yet at the same time keep a realistic number of layers to be comparable to a real world application.

The trivial example which I will present will involve a simple validator which merely validates whether a collection of Colors is not empty. Again, using FluentValidation, such a validator would look like this:

public class ColourCollectionValidator : AbstractValidator<IEnumerable<ColourPayloadDto>>
{
	public ColourCollectionValidator()
	{
		RuleFor(c => c)
			.Must(c => c.Any())
			.WithMessage("The payload must contain at least one colour.");
	}
}

So, lets look at the service which will perform the validation. The relevant method in this service will need to return both the ValidationResult and the collection itself. For that, I will use the ValueTuple type, which is a handy data-structure which helps us keep down the number of DTOs in our project (we will have enough DTOs already, without having to create another little one for this little job).

public class ColoursService : IColoursService
{
	private readonly IValidator<IEnumerable<ColourPayloadDto>> _colourValidator;

	public ColoursService(IValidator<IEnumerable<ColourPayloadDto>> colourValidator)
	{
		_colourValidator = colourValidator;
	}

	public async Task<(ValidationResult ValidationResult, List<ColourPayloadDto> DTOs)> GetColoursAsync()
	{
		/************* NOTE: hard coding a list here. Would normally be populated by database or API call *************/
		var colourPayloadDtos = new List<ColourPayloadDto>
		{
			new ColourPayloadDto{ Id = Color.Gainsboro.ToArgb(), IsKnownColour = Color.Gainsboro.IsKnownColor, Colour = Color.Gainsboro.Name},
			new ColourPayloadDto{ Id = Color.SaddleBrown.ToArgb(), IsKnownColour = Color.SaddleBrown.IsKnownColor  ,Colour =Color.SaddleBrown.Name},
			new ColourPayloadDto{ Id = Color.PaleGreen.ToArgb(), IsKnownColour = Color.PaleGreen.IsKnownColor,Colour= Color.PaleGreen.Name},
			new ColourPayloadDto{ Id = Color.DarkBlue.ToArgb(), IsKnownColour = Color.DarkBlue.IsKnownColor,Colour= Color.DarkBlue.Name}
		};

		var validationResult = await _colourValidator.ValidateAsync(colourPayloadDtos);
		
		return (validationResult, colourPayloadDtos);
	}
}

So the calling code will have returned a ValueTuple with both the ValidationResult and the collection. The other great thing about this type is the named members i.e. ValidationResult and DTOs (hmmm intellisense). Before we get to calling that code, lets pop on over to the query side of our architecture with the query object that will be acted upon by our QueryHandler. The query object is:

public class GetColourQuery : IRequest<Either<List<ColourPayloadDto>, ValidationResult>>
{
	// Nothing to pass to the QueryHandler, so no properties.
}

And that brings us to the custom type Either, which I have obtained from Mikhail Shilkov’s blog (thanks Mikhail!) I’ll just dump the code of Either here and will discuss it further when we examine the code which consumes it:

public class Either<TL, TR>
{
	private readonly TL left;
	private readonly TR right;
	private readonly bool isLeft;

	public Either(TL left)
	{
		this.left = left;
		this.isLeft = true;
	}

	public Either(TR right)
	{
		this.right = right;
		this.isLeft = false;
	}

	public T Match<T>(Func<TL, T> leftFunc, Func<TR, T> rightFunc)
	{
		if (leftFunc == null)
		{
			throw new ArgumentNullException(nameof(leftFunc));
		}

		if (rightFunc == null)
		{
			throw new ArgumentNullException(nameof(rightFunc));
		}

		return this.isLeft ? leftFunc(this.left) : rightFunc(this.right);
	}

	/// <summary>
	/// If right value is assigned, execute an action on it.
	/// </summary>
	/// <param name="rightAction">Action to execute.</param>
	public void DoRight(Action<TR> rightAction)
	{
		if (rightAction == null)
		{
			throw new ArgumentNullException(nameof(rightAction));
		}

		if (!this.isLeft)
		{
			rightAction(this.right);
		}
	}

	public TL LeftOrDefault() => this.Match(l => l, r => default(TL));

	public TR RightOrDefault() => this.Match(l => default(TR), r => r);

	public static implicit operator Either<TL, TR>(TL left) => new Either<TL, TR>(left);

	public static implicit operator Either<TL, TR>(TR right) => new Either<TL, TR>(right);
}

The next piece of code which is relevant is the Query Handler. As per the GetColourQuery, the return type of the Handle method is Either<List<ColourPayloadDto>, ValidationResult> (wrapped in a Task). If you look at the body of that method, depending on whether the ValidationResult is valid, it returns 1 of 2 types of objects i.e. a List or a ValidationResult. So, you can see where the nomenclature for Either came from. How is this done? By the implicit operators of the Either class (otherwise known as the User-defined conversion operators). Because it is implicit, we don’t need to explicitly cast to either List or ValidationResult.

The implicit operators also toggle the all-important isLeft field, which determines what gets returned when the Match method is called (you’ll see where that comes in a bit further on).
public class GetColourQueryHandler : IRequestHandler<GetColourQuery, Either<List<ColourPayloadDto>, ValidationResult>>
{
	private readonly IColoursService _coloursService;

	public GetColourQueryHandler(IColoursService coloursService)
	{
		_coloursService = coloursService;
	}

	public async Task<Either<List<ColourPayloadDto>, ValidationResult>> Handle(GetColourQuery request, CancellationToken cancellationToken)
	{
		var result = await _coloursService.GetColoursAsync();
		
		if (!result.ValidationResult.IsValid)
			return result.ValidationResult;

		return result.DTOs;     
	}
}

This enables us to write code like this (note the invocation of Match):

[HttpGet]
[Route("[action]")]
public async Task<IActionResult> GetColours()
{
	var colours = await _mediator.Send(new GetColourQuery());

	return colours.Match(
		res => OkResponse(colours.LeftOrDefault()),
		res => BadRequest(colours.RightOrDefault())
		);
}

Where validation has passed, the OkResponse will be passed the list of DTOs. Otherwise, the BadRequest will be passed the ValidationResult (which will be a failed validation).

So, again we have achieved an elegant implementation which has enabled us to filter up to the View the validation failure without throwing an exception. Our code will be more performant and our runtime will be all the more happier for it!

Feel free to hit me up in the comments if you have another way of dealing with validation failures that does not involved throwing exceptions.

Validation without Exceptions using a MediatR Pipeline Behavior

First post for 2019 (took me a while to get there).

This is the first post in a 2 post series:

  1. Validation without Exceptions using a MediatR Pipeline Behavior; and
  2. Manual Validation in A Mediatr RequestHandler without Exceptions

In the next 2 posts, I’m going to outline a couple of strategies that I use for returning validation failures in the business layer, without throwing an exception. The posts will also be in the context of Mediatr, which is a very handy library for modelling your HTTP requests (as either queries or commands – think CQRS).

Setting up Mediatr and creating pipelines is beyond the scope of this post. You will see a pipeline behavior being used in the post and can refer to the Mediatr documentation to get up and running quickly, if you are not familiar with Mediatr and how it works (the Github repo also has some good sample code).

The genesis of these posts came from my desire to handle validation failures gracefully and without throwing exceptions. This post will focus on validation in a Mediatr Pipeline behaviour. You may find a lot of code like this on StackOverflow, where an exception is thrown due to a validation failure/s. The exception is caught downstream and everything goes along swimmingly.

But this is not good. Whilst it is easy to implement (that’s a pro), there are a number of cons with this:

  • you should not use Exceptions for control flow. There’s a number of reasons for this, including the high perf cost in throwing exceptions. You don’t do it elsewhere in your code, so why do it for validation failures?
  • a validation failure is not exceptional in nature. It is actually expected. Hence, the validation check. Invoking the exception handling infrastructure should be confined to those things which are not expected.

With that in mind, I needed to find a way to return the validation failures to the client from a Mediatr pipeline, without just throwing (and later catching) an exception. It takes a little bit more effort, but I’m of the view that it is definitely worth it. To the code!

I’ll use an example of a request, where the submitted form:

  • is valid from a “form validation” perspective,
  • but invalid from a “business layer” validation perspective.

Lets say we have a user creation scenario and the user submits a POST request to the server with all valid fields (including the username). However, in this example, there is a business rule which checks to see if the username already exists (in the database). So, whilst the posted form is valid (username is not null), the overall request is ultimately invalid because the user submits a username which already exists in the database.

There’s a lot of moving parts in this, so I’ll start with a validator that is not central to our story. The following validator just validates the POST request. Nothin’ fancy, but it is used here to highlight the point that if the POST has valid inputs, the ModelState will be valid (FluentValidation, handily, bolts on any errors to ASP.NET’s ModelState):

public class CreateUserValidator: AbstractValidator<CreateUserDto>
{
	public CreateUserValidator()
	{
		RuleFor(m => m.Password).NotEmpty();
		RuleFor(m => m.UserName).NotEmpty();
	}
}

Next, I need to create a Command, as we are mutating data by creating a user. This is the command for that:

public class CreateNewUserCommand : IRequest<ValidateableResponse<ApiResponse<int>>>, IValidateable
{
    public CreateUserDto CreateUserDto { get; set; }
}

There’s a couple of key things I need to explain here. The IValidateable interface is just an empty marker interface. This tells my pipeline that this command requires validation. The ValidateableResponse class is the other big one here.

In the normal Mediatr workflow, I would just return the ApiResponse by itself. However, if validation fails, that will not be the object type which is returned. ApiResponse has no information about errors, which we need to convey back to the client. So, we wrap it in a ValidateableResponse, which looks like this:

public class ValidateableResponse
{
	private readonly IList<string> _errorMessages;

	public ValidateableResponse(IList<string> errors = null)
	{
		_errorMessages = errors ?? new List<string>();
	}

	public bool IsValidResponse => !_errorMessages.Any();

	public IReadOnlyCollection<string> Errors => new ReadOnlyCollection<string>(_errorMessages);
}

public class ValidateableResponse<TModel> : ValidateableResponse
	where TModel : class
{

	public ValidateableResponse(TModel model, IList<string> validationErrors = null)
		: base(validationErrors)
	{
		Result = model;
	}

	public TModel Result { get; }
}

And the CommandHandler will look like this:

public class CreateNewUserCommandHandler : IRequestHandler<CreateNewUserCommand, ValidateableResponse<ApiResponse<int>>>
{
	private readonly UserManager<IdpUser> _userManager;

	public CreateNewUserCommandHandler(UserManager<IdpUser> userManager)
	{
		_userManager = userManager;
	}

	public async Task<ValidateableResponse<ApiResponse<int>>> Handle(CreateNewUserCommand request,
		CancellationToken cancellationToken)
	{
		var dto = request.Dto;

		var newAppUser = new IdpUser
		{
			UserName = dto.UserName.Trim(),                
			Password = dto.Password.Trim()
		};

		var result = await _userManager.CreateAsync(newAppUser, dto.Password);

		if (result.Succeeded)
		{
			await _userManager.AddClaimsAsync(
				newAppUser,
				new[] 
				{
					new Claim("access", dto.UserRole),
					new Claim("given_name", dto.UserName)
				}
			);
			
            var apiResponse = new ApiResponse<int>
            {
                Data = newAppUser.Id,
                Outcome = new OperationOutcome
                {
                    Message = string.Empty, OpResult = OpResult.Success
                }
            };			

			return new ValidateableResponse<ApiResponse<int>>(apiResponse);
		}

		return new ValidateableResponse<ApiResponse<int>>(
			null,
			result.Errors
				.Select(e => string.Concat(e.Code, GeneralPurpose.UniqueDelimiter, e.Description))
				.ToList()
			);
	}
}

By doing this, despite the outcome, the same type of object is returned i.e. a ValidateableResponse. If all goes well, we just get the Data property, which in this case, will be an ApiResponse. If validation fails, there will be a populated Errors collection. The outcome is easily checked by querying the IsValidResponse property. This enables us to write code like this:

[HttpPost]
[Route("[action]")]
public async Task<IActionResult> CreateUser([FromBody]CreateUserDto userDto)
{
    var response = await _mediator.Send(new CreateNewUserCommand {CreateUserDto = userDto});

	return result.IsValidResponse
		? CreatedAtRoute(routeValues: new
		{
			controller = "User",
			action = nameof(UserController.GetUser),
			id = result.Result.Data
			version = HttpContext.GetRequestedApiVersion().ToString()
		}, result.Result)
		: BadRequestResponse(Enumerable.Empty<string>(), operationOutcome: new OperationOutcome
		{
			OpResult =OpResult.Fail, 
			IsError = false,
			IsValidationFail = true,
			Errors = result.Errors
		});

}

As you can see, no try/catch block (we will save that for the custom action filters or middleware).

Finally, let’s now look at the pipeline behavior class which draws this all together; the component which validates our command and returns a ValidateableResponse , with a populated Errors list, where validation has failed:

public class BusinessValidationPipeline<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
	where TResponse : class
	where TRequest : IValidateable
{
	private readonly IValidator<TRequest> _compositeValidator;
	private readonly ILogger<TRequest> _logger;
	private readonly ICurrentUser _currentUser;

	public BusinessValidationPipeline(IValidator<TRequest> compositeValidator, ILogger<TRequest> logger, ICurrentUser currentUser)
	{
		_compositeValidator = compositeValidator;
		_logger = logger;
		_currentUser = currentUser;
	}

	public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
	{
		var result = await _compositeValidator.ValidateAsync(request, cancellationToken);

		if (!result.IsValid)
		{
			_logger.LogError(EventIDs.EventIdPipelineThrown,
				MessageTemplates.ValidationErrorsLog,
				result.Errors.Select(s => s.ErrorMessage).Aggregate((acc, curr) => acc += string.Concat("_|_", curr)),
				_currentUser.UserName
				);

			var responseType = typeof(TResponse);

			if (responseType.IsGenericType)
			{
				var resultType = responseType.GetGenericArguments()[0];
				var inValidResponse = typeof(ValidateableResponse<>).MakeGenericType(resultType);

				var invalidResponse =
					Activator.CreateInstance(inValidResponse, null, result.Errors.Select(s => s.ErrorMessage).ToList()) as TResponse;

				return invalidResponse;
			}
		}

		var response = await next();

		return response;
	}
}

If the request fails validation, log it, then generate a ValidateableResponse. This must be done and returned before the next pipeline behavior is invoked (to short-circuit the pipeline). Thus, it is returned before the call to await next() which would be called if everything went well.

Another really cool aspect of this setup is that this pipeline behavior won’t even run unless the TRequest implements IValidateable. Notice how the following generic constraint is placed on the TRequest parameter – where TRequest : IValidateable. To achieve this, you use dependency injection to ensure that this part of the pipeline does not even get injected where the command, which is moving through the pipleline, does not implement IValidateable. So, no need for any if statement in the pipleline behavior class like if(TRequest is IValidateable). An example of such an IOC configuration, using SimpleInjector, would look like this:

Container.RegisterSingleton<IMediator, Mediator>();
Container.Register(typeof(IRequestHandler<,>), assemblies, Lifestyle.Singleton);

Container.Collection.Register(typeof(IPipelineBehavior<,>), new[]
{                
	typeof(LogContextPipeline<,>),
	typeof(BusinessValidationPipeline<,>),
	typeof(TransactionPipelineBehaviour<,>),
	typeof(GenericPipelineBehavior<,>)
});

I’ll also just touch on the reflection which has been used to create the return object where validation fails. Obviously, as this pipeline behavior serves a variety of requests, generics is used to provide that flexibility. That also means we can’t just “new” up an object as we don’t know the closed generic type of TResponse. So, we use reflection to interrogate the response object and from there are able to construct the ValidateableResponse, using the Activator class. Some people will assert that reflection is expensive. It’s not. It really isn’t (unless you are building something where performance is absolutely critical, like a web-server). The perf expense of such a manoeuvre is negligible and pales in comparison to the expense of throwing an exception.

My next post is going to deal with the same notion of validations without exceptions, except the validation will happen in a different place (in the business layer layer itself [i.e. not in a pipeline behavior]) and I will be using a functional programming technique to achieve that end.