Trying to respond consistently in case of validation failure

Hello,

In case of success or failure, I am trying to achieve maximum consistency while responding back to consumer. For example as shown below when everything goes fine my service is responding nicely with 200 http status code.

200 - Status - Success

{
    "mainCategories": [
        {
            "id": 3,
            "code": "Kids",
            "nameEn": "Kids",
            "imageId": 0
        }
    ],
    "responseDetails": {
        "reqCorrelationId": "86bd9a54-24da-4d72-a99b-869c1e767b8c",
        "errors": [
            {
                "errorCode": 0,
                "errorMessage": "Success"
            }
        ]
    }
}

here are the code artifacts you might need to consult that how I am trying to do…

Validator Code

  public class GetMainCategoryValidator : AbstractValidator<MainCategoryByCodeRequest>
  {
      public GetMainCategoryValidator()
      {
          RuleSet(ApplyTo.Get, () =>
          {
              RuleFor(x => x.CategoryName).NotEmpty().WithErrorCode("1001").WithMessage("code cannot be empty");                
          });

      }
  }

MainCategoryByCodeRequest

 [Route("/MainCategoryByCode/", "GET")]
 [Route("/MainCategoryByCode/{categoryName}", "GET")]
 public class MainCategoryByCodeRequest :IReturn<MainCategoryByCodeResponse>
 {
     public MainCategoryByCodeRequest() { }

     public string? CorrelationId { get; set; }

     public DateTime? RequestTimestamp { get; set; }

     public string? Language { get; set; }
     public string? CategoryName { get; set; }
 }

Response DTO

 public class MainCategoryByCodeResponse
 {
     public MainCategoryByCodeResponse()
     {
         this.MainCategories = new List<MainCategory>();          
     }
     public ResponseStatus? ResponseStatus { get; set; }
     public List<MainCategory> MainCategories { get; set; }  
     public ErrorsDetailResponse? ResponseDetails { get; set; }
 }

This is how I have registered the validator in configure method of AppHost

appHost.RegisterAs<GetMainCategoryValidator, IValidator<MainCategoryByCodeRequest>>();

So far so good.

Now as mentioned earlier I am trying to achieve maximum consistency in the response. In case of validation failure I want to respond like this

{
    "responseStatus": {        
		"reqCorrelationId": "86bd9a54-24da-4d72-a99b-869c1e767b8c",
			"errors": [
				{
					"errorCode": "1001",
					"errorMessage": "code cannot be empty"
				},
				{
					"errorCode": "1002",
					"errorMessage": "code must be 10 characters long"
				}
			]
    },
    "mainCategories": []
}

It looks like that while using the ValidationFeature I may not able to achieve exactly what I am looking for, rather I have to do validations/verifications inside the service to produce the desired result.

Kindly advise.

You can’t change the ResponseStatus schema which is a fixed concrete Type. All ServiceStack Client Libraries and built-in UIs rely on error information being returned in a populated ResponseStatus property so you’d always want to return that.

If you want to return additional information in the ResponseStatus Type I’d recommend adding it to its Meta Dictionary by overriding OnExceptionTypeFilter in your AppHost:

public override void OnExceptionTypeFilter(Exception ex, ResponseStatus responseStatus)
{
    base.OnExceptionTypeFilter(ex, responseStatus);
    if (ex is ValidationException validationEx)
    {
        responseStatus.Meta ??= new();
        responseStatus.Meta["field"] = ...
    }
}

Hi @mythz,

Appreciate your time and support.

Regards