Search code examples
c#servicestackfluentvalidation

ServiceStack - FluentValidation


I have a question about using a FluentValidation with ServiceStack.

For example:

[Route("/customers/{Id}", "PUT")]
public class UpdateCustomer : IReturn<Customer>
{
    public int Id { get; set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }
}

[Route("/customers/{Id}", "DELETE")]
public class DeleteCustomer : IReturnVoid
{
    public int Id { get; set; }
}

public class Customer
{
    public int Id { get; set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }
}

When I'm updating customer info, I want to validate for example all params, but when deleting it for example, I just want to make sure that Id is for example positive int. So, FirstName, LastName, etc. everything else I don't care in that case.

If I implement FluentValidator on Customer class, I will have to put all the logic inside the validator for that (to apply different rules based on request route)? Or there's more elegant way for doing that?


Solution

  • The validators should only be on the Request DTO's, e.g:

    public class UpdateCustomerValidator : AbstractValidator<UpdateCustomer>
    {
        public UpdateCustomerValidator()
        {
            RuleFor(r => r.Id).GreaterThan(0);
            RuleFor(r => r.FirstName).NotEmpty();
            RuleFor(r => r.LastName).NotEmpty();
        }
    }
    

    and likewise for DeleteCustomer, e.g:

    public class DeleteCustomerValidator : AbstractValidator<DeleteCustomer>
    {
        public DeleteCustomerValidator()
        {
            RuleFor(r => r.Id).GreaterThan(0);
        }
    }
    

    Although creating a whole validator for a single field can be overkill so you could instead just add the validation in your Service, e.g:

    public class CustomerServices : Service
    {
        public void Any(DeleteCustomer request)
        {
            if (request.Id <= 0)
                throw new ArgumentException("Id Required", "Id")
    
            Db.DeleteById<Customer>(request.Id);
        }
    }