2
votes

Disclaimer: I'm fairly new to ServiceStack

Given the following Service:

public class TestService : Service
{
    public TestResponse Get(Test request)
    {
        if (String.IsNullOrEmpty(request.Message))
            throw new ArgumentException("Message is required");

        return new TestResponse();
    }
}

and the following request/response DTO's :

[Route("/test", "GET")]
public class Test : IReturn<TestResponse>
{
    public string Message { get; set; }
}

public class TestResponse
{
    public IList<Test> TestList { get; set; }
}

I would expect the following response when I try to access /test :

{
    "responseStatus": {
        "errorCode": "ArgumentException",
        "message": "Message is required",
        "errors": []
    }
}

Instead I get an empty JSON response. It is however returning the correct status code (400 Bad Request).

I thought it would be quite common to name your DTO's in this manner in ServiceStack with Something and then SomethingResponse. To get it to return the exception as a serialized ResponseStatus object I have discovered that I can either rename my request DTO from Test to TestRequest and/or include a ResponseStatus property in my response DTO.

Is this expected behaviour?

Update

I should include that the issue only occurs if the name of my response DTO ends with Response (case sensitive). If my request/response DTO's are called Foo and Bar respectively, I receive a properly formatted JSON response with the error.

1

1 Answers

5
votes

Firstly, don't use interfaces on DTOs and for the docs on ServiceStack Error Responses it says:


Error Response Types

The Error Response that gets returned when an Exception is thrown varies on whether a conventionally-named {RequestDto}Response DTO exists or not.

The {RequestDto}Response is returned, regardless of the service method's response type. If the {RequestDto}Response DTO has a ResponseStatus property, it is populated otherwise no ResponseStatus will be returned.

A generic ErrorResponse gets returned with a populated ResponseStatus property.

The Service Clients transparently handles the different Error Response types, and for schema-less formats like JSON/JSV/etc there's no actual visible difference between returning a ResponseStatus in a custom or generic ErrorResponse - as they both output the same response on the wire.


Given the New API lets you return clean responses whilst still retaining the Error information, your DTOs should be either:

[Route("/test", "GET")]
public class Test : IReturn<TestResponse>
{
    public string Message { get; set; }
}

public class TestResponse
{
    public List<Test> TestList { get; set; }

    public ResponseStatus ResponseStatus { get; set; }
} 

Or you can go without the Response DTO and return the clean list, e.g:

[Route("/test", "GET")]
public class Test : IReturn<List<Test>>
{
    public string Message { get; set; }
}

public class TestService : Service
{
    public List<Test> Get(Test request)
    {
        if (String.IsNullOrEmpty(request.Message))
            throw new ArgumentException("Message is required");

        return new List<Test>();
    }
}