Skip to content

Instantly share code, notes, and snippets.

@stormwild
Forked from dj-nitehawk/1-BaseQuestion.cs
Created October 1, 2024 09:04
Show Gist options
  • Save stormwild/c90acd9226ad7636507e6696de04a228 to your computer and use it in GitHub Desktop.
Save stormwild/c90acd9226ad7636507e6696de04a228 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