ThommyB
ThommyB

Reputation: 1546

servicestack - make request dto parameters REQUIRED

I have a request DTO like so:

[Route("/appusers/resetpwd/{UserId}", "PUT")]
public class ResetPassword : IReturn<AppUserDto>
{
    public Guid UserId { get; set; }
    public string OldPassword { get; set; }
    public string NewPassword { get; set; }

    public ResetPassword(Guid userId, string oldPassword, string newPassword)
    {
        UserId = userId;
        OldPassword = oldPassword;
        NewPassword = newPassword;
    }
}

The metadata page shows the three properties as REQUIRED = No in the list. Can they be made required? Or does this simply mean I have to check them on the server and throw an exception as is explained in the wiki?

Upvotes: 3

Views: 776

Answers (1)

mythz
mythz

Reputation: 143284

You can declare required fields using ServiceStack's built-in ValidationFeature, e.g:

Enable in AppHost with:

Plugins.Add(new ValidationFeature());

//Register All Validators in Assembly
container.RegisterValidators(typeof(MyValidator).Assembly);

Configure with:

public class ResetPasswordValidator : AbstractValidator<ResetPassword>
{
    public ResetPasswordValidator()
    {
        RuleFor(x => x.UserId).NotEmpty();
        RuleFor(x => x.OldPassword).NotEmpty();
        RuleFor(x => x.NewPassword).NotEmpty();
    }
}

Designing Message-based and HTTP APIs

Note some serializers require all DTO's to have a parameterless constructor. Also Resetting a Users Password isn't a valid PUT Operation which is expected to be idempotent and roughly translates to "PUT this resource at this location", it's more appropriately sent as a POST.

You can find some tips on designing message-based and HTTP APIs in ServiceStack in this previous answer where I would rewrite this Request DTO as:

[Route("/users/{UserId}/reset-password", "POST")]
public class ResetPassword : IReturn<ResetPasswordResponse>
{
    public Guid UserId { get; set; }
    public string OldPassword { get; set; }
    public string NewPassword { get; set; }
}

Although if this Service doesn't need to return a response it can also just return void, e.g:

public class ResetPassword : IReturnVoid { ... }

And implemented in your Service with:

public void Any(ResetPassword request) { ... }

Upvotes: 2

Related Questions