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)

	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):

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(
					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>>(
				.Select(e => string.Concat(e.Code, GeneralPurpose.UniqueDelimiter, e.Description))

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:

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)
				result.Errors.Select(s => s.ErrorMessage).Aggregate((acc, curr) => acc += string.Concat("_|_", curr)),

			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[]

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.

Using Stuff to Clean Up String Concatenation

In my last post, I covered the simple, yet handy, STUFF function. It’ll take a string and “stuff it right in there”. Today, I want to cover a real work scenario where I use it quite often. I’ll use the AdventureWorks database (“AWD”) to demonstrate.

Joins create rows. If you run the following query against the AWD, you’ll see the SalesOrderId repeated for each SalesOrderDetail row:

	Sales.SalesOrderHeader soh
	Sales.SalesOrderDetail sod on sod.SalesOrderID = soh.SalesOrderID

But there are times where you want only 1 row for each SalesOrderID. And so we need a mechanism which can effectively concatenate all the SalesOrderDetailIDs for each SalesOrderID and return it as a single cell, adjacent to the corresponding SalesOrderID.

Consider the following query:

	,(SELECT CHAR(44) + CAST(sod.SalesOrderDetailID AS NVARCHAR(MAX))
			 FROM Sales.SalesOrderDetail sod
			 WHERE soh.SalesOrderID = sod.SalesOrderID
			 FOR XML PATH('row'), ROOT('result'),TYPE) AS SalesOrderDetailIDs
FROM Sales.SalesOrderHeader soh
ORDER BY soh.SalesOrderID

which yields the following resultset:

Figure 1

You can see that via the use of the XML query syntax and a correlated subquery, I have gone a long way to achieving our goal. All the SalesOrderDetailIDs are in a cell such that there is only 1 row for each SalesOrderID. But we are not interested in well-formed XML, having the XML type (which was done by using the TYPE directive and specifying a ROOT element). We need to peel back the XML elements and extract the value within. We can use the xQuery API to return an NVARCHAR(MAX), which has effectively returned the contents of each XML “row” element.

So now our query looks like this:

	,((SELECT CHAR(44) + CAST(sod.SalesOrderDetailID AS NVARCHAR(MAX))
			 FROM Sales.SalesOrderDetail sod
			 WHERE soh.SalesOrderID = sod.SalesOrderID
			 FOR XML PATH('row'),TYPE, ROOT('result')).value('/result[1]','varchar(max)')) AS SalesOrderDetailIDs
FROM Sales.SalesOrderHeader soh
ORDER BY soh.SalesOrderID

But we’re not quite there. We have 1, small, pesky comma at the beginning of the NVARCHAR, an example of which looks like this:


This is where STUFF comes in. If we were to deal with this in isolation, it would look like this:

SELECT STUFF(',1,2,3,4,5,6,7,8,9,10,11,12', 1,1, N'')

We are telling STUFF to go to the first character, delete 1 character and replace it with an empty string. That’s how we remove the leading comma. Incorporating that into the main query, we have our final code:

			 FROM Sales.SalesOrderDetail sod
			 WHERE soh.SalesOrderID = sod.SalesOrderID
			 FOR XML PATH('row'),TYPE, ROOT('result')).value('/result[1]','varchar(max)'),1,1,N'')) AS SalesOrderDetailIDs
FROM Sales.SalesOrderHeader soh
ORDER BY soh.SalesOrderID

And our resultset:

Figure 2

Note: Rob Farley, in his post Handling special characters with FOR XML PATH, notes that you can:

  1. Remove the ROOT
  2. Change the xQuery to .value('.','varchar(max)')

Rob also makes the point that “it’s always felt strange to me to be returning something which I declare to be XML (using TYPE) without it being well-formed”. I agree with this. It’s a bit weird and makes it harder to see what is going on. But I wanted to point that out for completeness.

Otherwise, that’s a real world example usage of STUFF.

Stuff – The SQL Server Function

I want to dedicate a small post to STUFF. It’s a pretty handy little function in SQL Server which deletes a sequence of characters from a source string and then inserts another sequence of characters into the source string, starting at a specified position. The best way to show how it works is with examples.

Lets turn the word inimical into inimitable:

SELECT STUFF('inimical', 6, 3, 'table')

outputs: inimitable

STUFF is not 0-indexed. So, it goes to the 6th character in the string, deletes 3 characters and replaces that with the string in the last parameter. Now we have inimitable.

Add a colon into a time:

SELECT STUFF('1159', 3, 0, ':') 

outputs: 11:59

Mask a credit card number:

DECLARE @CreditCardNumber VARCHAR(20)
SET @CreditCardNumber = '9876-5432-0987-6543'

SELECT STUFF(@CreditCardNumber, 1, LEN(@CreditCardNumber) - 4, REPLICATE('X', LEN(@CreditCardNumber) - 4)) AS [Output]


So, STUFF is pretty cool. But there is something which I use it for quite regularly in my work. As it is quite involved, I’ll do a separate post to walk through it (this post is really just “setting the table” for that one).

Migrating Away from Nuget.exe

David Ebbo wrote a great blog post way back in 2014 about migrating away from using Nuget.exe in your solutions (it was the old way of doing it). Every now and again, I come across an old project which requires such a migration. The Nuget documentation used to have a page which explained how to do that, but they seem to have removed it. So, I will outline the steps here.

So, to recap, remember when we used to have the Nuget.exe as part of the solution?

Figure 1 – exe in the solution

We need to remove this and move to the modern way of implementing Nuget package restore.

  1. Delete the hidden .nuget directory. Nuke it from orbit (it’s the only way to be sure!).
  2. Open all your .proj files in a text editor and remove references to nuget.targets.

With Step 2, you will be looking for something like the following:

<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />

And possibly also:

<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see The missing file is {0}.</ErrorText>
    <Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />

Be gone with that stuff.

In the solution file, it will look like this:

Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{E6774590-A85E-47D2-8603-10EAAE39A240}"
	ProjectSection(SolutionItems) = preProject
		.nuget\NuGet.Config = .nuget\NuGet.Config
		.nuget\NuGet.exe = .nuget\NuGet.exe
		.nuget\NuGet.targets = .nuget\NuGet.targets

And now you are done. So long as Visual Studio is configured to update packages automatically, you are good to go.