NServiceBus.Community.Validation
Message validation using DataAnnotations and FluentValidation
Install / Use
/learn @NServiceBusCommunity/NServiceBus.Community.ValidationREADME
<img src="/src/icon.png" height="25px"> NServiceBus.Community.Validation
Message validation using DataAnnotations and FluentValidation.
See Milestones for release notes.
<!--- StartOpenCollectiveBackers -->Already a Patron? skip past this section
Community backed
It is expected that all developers become a Patron to use NServiceBus Community Extensions. Go to licensing FAQ
Sponsors
Support this project by becoming a Sponsor. The company avatar will show up here with a website link. The avatar will also be added to all GitHub repositories under the NServiceBusCommunity organization.
Patrons
Thanks to all the backing developers. Support this project by becoming a patron.
<img src="https://opencollective.com/nservicebuscommunity/tiers/patron.svg?width=890&avatarHeight=60&button=false"><a href="#" id="endofbacking"></a>
<!--- EndOpenCollectiveBackers -->NServiceBus.FluentValidation
Uses FluentValidation to validate incoming and outgoing messages.
NuGet package
https://www.nuget.org/packages/NServiceBus.Community.FluentValidation/
Usage
FluentValidation message validation can be enabled using the following:
<!-- snippet: FluentValidation --><a id='snippet-FluentValidation'></a>
endpointConfiguration.UseFluentValidation();
serviceCollection.AddValidatorsFromAssemblyContaining<TheMessage>();
<sup><a href='/src/NServiceBus.FluentValidation.Tests/Snippets/Usage.cs#L5-L10' title='Snippet source file'>snippet source</a> | <a href='#snippet-FluentValidation' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->This will result in, when an invalid message being detected, a validation exception being thrown and that message being handled by Recoverability. The validation exception will also be added to Unrecoverable exceptions to avoid unnecessary retries.<!-- singleLineInclude: validationexception. path: /src/validationexception.include.md -->
By default, incoming and outgoing messages are validated.
To disable for incoming messages use the following:
<!-- snippet: FluentValidation_disableincoming --><a id='snippet-FluentValidation_disableincoming'></a>
endpointConfiguration.UseFluentValidation(incoming: false);
<sup><a href='/src/NServiceBus.FluentValidation.Tests/Snippets/Usage.cs#L12-L16' title='Snippet source file'>snippet source</a> | <a href='#snippet-FluentValidation_disableincoming' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->To disable for outgoing messages use the following:
<!-- snippet: FluentValidation_disableoutgoing --><a id='snippet-FluentValidation_disableoutgoing'></a>
endpointConfiguration.UseFluentValidation(outgoing: false);
<sup><a href='/src/NServiceBus.FluentValidation.Tests/Snippets/Usage.cs#L18-L22' title='Snippet source file'>snippet source</a> | <a href='#snippet-FluentValidation_disableoutgoing' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->Enabling validation on outgoing message will result in the validation exception be thrown in the context of the sender, instead of during message processing on the receiving endpoint. This can be particularly helpful in development and/or debugging scenarios since the stack trace and debugger will more accurately reflect the cause of the invalid message.<!-- singleLineInclude: validationoutgoing. path: /src/validationoutgoing.include.md -->
Messages can then have an associated validator:
<!-- snippet: FluentValidation_message --><a id='snippet-FluentValidation_message'></a>
public class TheMessage :
IMessage
{
public string Content { get; set; } = null!;
}
public class MyMessageValidator :
AbstractValidator<TheMessage>
{
public MyMessageValidator() =>
RuleFor(_ => _.Content)
.NotEmpty();
}
<sup><a href='/src/NServiceBus.FluentValidation.Tests/Snippets/TheMessage.cs#L1-L17' title='Snippet source file'>snippet source</a> | <a href='#snippet-FluentValidation_message' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->Accessing the current pipeline context
In some cases a validator may need to use data from the current message context.
The current message context can be accessed via two extension methods:
- The current message headers can be accessed via
FluentValidationExtensions.Headers(this CustomContext customContext) - The current
ContextBagcan be accessed viaFluentValidationExtensions.ContextBag(this CustomContext customContext).
<a id='snippet-FluentValidation_ContextValidator'></a>
public class ContextValidator :
AbstractValidator<TheMessage>
{
public ContextValidator() =>
RuleFor(_ => _.Content)
.Custom((propertyValue, validationContext) =>
{
var messageHeaders = validationContext.Headers();
var bag = validationContext.ContextBag();
if (propertyValue != "User" ||
messageHeaders.ContainsKey("Auth"))
{
return;
}
validationContext.AddFailure("Expected Auth header to exist");
});
}
<sup><a href='/src/NServiceBus.FluentValidation.Tests/Snippets/ContextValidator.cs#L3-L24' title='Snippet source file'>snippet source</a> | <a href='#snippet-FluentValidation_ContextValidator' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->Validator scanning
Validators are registered and resolved using dependency injection. Assemblies can be added for validator scanning using either a generic Type, a Type instance, or an assembly instance.
<!-- snippet: FluentValidation_AddValidators --><a id='snippet-FluentValidation_AddValidators'></a>
endpointConfiguration.UseFluentValidation();
serviceCollection.AddValidatorsFromAssemblyContaining<MyMessage>();
serviceCollection.AddValidatorsFromAssemblyContaining(typeof(SomeOtherMessage));
serviceCollection.AddValidatorsFromAssembly(assembly);
<sup><a href='/src/NServiceBus.FluentValidation.Tests/Snippets/Usage.cs#L27-L34' title='Snippet source file'>snippet source</a> | <a href='#snippet-FluentValidation_AddValidators' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->By default, there are two exception scenarios when adding validators. An exception will be thrown if:
- No validators are found in an assembly that is scanned.
- Any non-public validators are found in an assembly that is scanned.
These exception scenarios can be excluded using the following:
<!-- snippet: FluentValidation_IgnoreValidatorConventions --><a id='snippet-FluentValidation_IgnoreValidatorConventions'></a>
endpointConfiguration.UseFluentValidation();
serviceCollection.AddValidatorsFromAssembly(
assembly,
throwForNonPublicValidators: false,
throwForNoValidatorsFound: false);
<sup><a href='/src/NServiceBus.FluentValidation.Tests/Snippets/Usage.cs#L39-L47' title='Snippet source file'>snippet source</a> | <a href='#snippet-FluentValidation_IgnoreValidatorConventions' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->NServiceBus.DataAnnotations
Uses System.ComponentModel.DataAnnotations to validate incoming and outgoing messages.
NuGet package
https://www.nuget.org/packages/NServiceBus.DataAnnotations/
Usage
DataAnnotations message validation can be enabled using the following:
<!-- snippet: DataAnnotations --><a id='snippet-DataAnnotations'></a>
configuration.UseDataAnnotationsValidation();
<sup><a href='/src/NServiceBus.DataAnnotations.Tests/Snippets/Usage.cs#L5-L9' title='Snippet source file'>snippet source</a> | <a href='#snippet-DataAnnotations' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->This will result in, when an invalid message being detected, a validation exception being thrown and that message being handled by Recoverability. The validation exception will also be added to Unrecoverable exceptions to avoid unnecessary retries.<!-- singleLineInclude: validationexception. path: /src/validationexception.include.md -->
By default, incoming and outgoing messages are validated.
To disable for incoming messages use the following:
<!-- snippet: DataAnnotations_disableincoming --><a id='snippet-DataAnnotations_disableincoming'></a>
configuration.UseDataAnnotationsValidation(
Languages
Security Score
Audited on Apr 3, 2026
