Skip to content

Instantly share code, notes, and snippets.

@dj-nitehawk
Last active January 10, 2024 10:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dj-nitehawk/d5e5b64f8fdc7ce90656305c6a40174e to your computer and use it in GitHub Desktop.
Save dj-nitehawk/d5e5b64f8fdc7ce90656305c6a40174e to your computer and use it in GitHub Desktop.
Validator inheritance for polymorphic DTOs.
[
JsonPolymorphic(TypeDiscriminatorPropertyName = "_t"),
JsonDerivedType(typeof(MultiChoiceQuestionRequest), "mcq"),
JsonDerivedType(typeof(RatingQuestionRequest), "rq")
]
public class BaseQuestionRequest
{
public int Id { get; set; }
}
public class BaseQuestionRequestValidator : Validator<BaseQuestionRequest>
{
public BaseQuestionRequestValidator()
{
RuleFor(r => r.Id).NotEmpty();
}
}
public class MultiChoiceQuestionRequest : BaseQuestionRequest
{
public string Question { get; set; }
}
public class MultiChoiceQuestionRequestValidator : Validator<MultiChoiceQuestionRequest>
{
public MultiChoiceQuestionRequestValidator()
{
Include(new BaseQuestionRequestValidator());
RuleFor(r => r.Question).NotEmpty();
}
}
{
"questions" : [
"_t" : "mcq",
"id" : 1,
"question" : "question text"
]
}
public class RatingQuestionRequest : BaseQuestionRequest
{
public int Rating { get; set; }
}
public class RatingQuestionRequestValidator : Validator<RatingQuestionRequest>
{
public RatingQuestionRequestValidator()
{
Include(new BaseQuestionRequestValidator());
RuleFor(r => r.Rating).GreaterThan(1);
}
}
{
"questions" : [
"_t" : "rq",
"id" : 1,
"rating" : 2
]
}
public class Request
{
public List<BaseQuestionRequest> Questions { get; set; } = [];
}
public class Validator : Validator<Request>
{
public Validator()
{
RuleForEach(x => x.Questions).SetInheritanceValidator(
v =>
{
v.Add(new MultiChoiceQuestionRequestValidator());
v.Add(new RatingQuestionRequestValidator());
});
}
}
sealed class MyEndpoint : Endpoint<Request>
{
public override void Configure()
{
Post("echo");
AllowAnonymous();
}
public override async Task HandleAsync(Request r, CancellationToken c)
{
await SendAsync(r);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment