Register request requires Email

After having updated from v6.11 to v8.x I am presently receiving “‘Email’ must not be empty” from Register requests during automated account creation between systems where there are no email addresses on the source side and no need for one on the target ServiceStack side.

The AuthFeature plugin has the ValidateUniqueEmails property set false and we’re not running a customer registration validator. That property was set back in 2021 back when we were still running 4.5.14 to enable the automated processing.

Creating and registering a custom RegistrationValidator with rules only for the properties that we require doesn’t change the response from the Auth service.

Is there anything else in particular that I should do or look at to enable my desired behavior of not having the Email property being required?

Do you have a full StackTrace of the Exception?

Sure thing. Here is the thrown client exception:

   at ServiceStack.ServiceClientBase.ThrowWebServiceException[TResponse](Exception ex, String requestUri) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.Client/ServiceClientBase.cs:line 910
   at ServiceStack.ServiceClientBase.ThrowResponseTypeException[TResponse](Object request, Exception ex, String requestUri) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.Client/ServiceClientBase.cs:line 846
   at ServiceStack.ServiceClientBase.HandleResponseException[TResponse](Exception ex, Object request, String requestUri, Func`1 createWebRequest, Func`2 getResponse, TResponse& response) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.Client/ServiceClientBase.cs:line 797
   at ServiceStack.ServiceClientBase.Send[TResponse](String httpMethod, String relativeOrAbsoluteUrl, Object request) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.Client/ServiceClientBase.cs:line 1405
   at ServiceStack.ServiceClientBase.Post[TResponse](Object requestDto) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.Client/ServiceClientBase.cs:line 1563
   at ServiceStack.ServiceClientBase.Send[TResponse](Object request) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.Client/ServiceClientBase.cs:line 633
   at ServiceStack.ServiceGatewayExtensions.Send[TResponse](IServiceGateway client, IReturn`1 request) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.Client/ServiceGatewayExtensions.cs:line 24

Also, for what it is worth, the Register request is made on with unauthenticated IServiceClient instance.

I mean the Server StackTrace, i.e. to see the source of the Exception

I added a ServiceExceptionHandler on the server side and the inner break point is not hit.

The ServerStackTrace property on the client exception is null.

Looking at the response body further shows that it isn’t just the Email property that the Register request has problems with, but also the empty FirstName and LastName properties which are set at a later point after the automated account creation takes place:

{"responseStatus":{"errorCode":"NotEmpty","message":"'Email' must not be empty.","errors":[{"errorCode":"NotEmpty","fieldName":"Email","message":"'Email' must not be empty.","meta":{"PropertyName":"Email"}},{"errorCode":"NotEmpty","fieldName":"FirstName","message":"'First Name' must not be empty.","meta":{"PropertyName":"First Name","PropertyValue":""}},{"errorCode":"NotEmpty","fieldName":"LastName","message":"'Last Name' must not be empty.","meta":{"PropertyName":"Last Name","PropertyValue":""}}]}}

I’m assuming it’s because the ValidationFeature is now pre-registered.

and it’s using the default RegistrationValidator, which you can register to use your own instead with only the validation you want, see the vue-mjs Configure.Auth.cs for an example:

// Custom Validator to add custom validators to built-in /register Service
// requiring DisplayName and ConfirmPassword
public class CustomRegistrationValidator : RegistrationValidator
{
    public CustomRegistrationValidator()
    {
        RuleSet(ApplyTo.Post, () =>
        {
            RuleFor(x => x.DisplayName).NotEmpty();
            RuleFor(x => x.ConfirmPassword).NotEmpty();
        });
    }
}

Then register it in the IOC against IValidator<Register>, e.g:

public class ConfigureAuth : IHostingStartup
{
    public void Configure(IWebHostBuilder builder) => builder
      .ConfigureAppHost(appHost => {
          var appSettings = appHost.AppSettings;
          appHost.Plugins.Add(new AuthFeature(() => new CustomUserSession(),
              new IAuthProvider[] {
                  new CredentialsAuthProvider(appSettings),
                  //...
              }) {
                  HtmlRedirect = "/signin"
              });

          //Enable /register Service
          appHost.Plugins.Add(new RegistrationFeature());

          //override default registration validation with your own custom impl
          appHost.RegisterAs<CustomRegistrationValidator,IValidator<Register>>();
      });
}

The custom validator sorted out the issue.

Thank you for your assistance, mythz.

1 Like