2
votes

I am quite new to ServiceStack, I am following the example at http://nilsnaegele.com/codeedge/servicestack1.html which I have been finding useful. I read that explicit StatusResponse fields in DTO Response declarations were not required in the new API, but I dont appear to be getting the expected behaviour here.

Using ServiceStack 3.9.71.

I introduced an Exception in the EntryService post to get a feel for the client handling.

public object Post(Entry request)
{
    if (request.Quantity == 3)
    {
        throw new WebException("post entry");
    }
}

With

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

Then in the client side when posting an Entry handle the exception.

    try
    {
        var entryRequest = new Entry {Quantity = quantity, EntryTime = DateTime.Now};
        var response = client.Send(entryRequest);
        Console.WriteLine("Response: {0}", response.Id);
    }
    catch (WebServiceException wse)
    {
        // At this point wse.ResponseStatus field is null.
    }

I tested out explicitly adding the ResponseStatus field to EntryResponse and this produced the ResponseStatus filled in on the client with no change to the client code.

I then tried throwing an exception in StatusRequestService as follows to see if the second web service client request would behave the same way, and it appears it behaves differently.

public object Any(StatusRequest request)
{
    if (request.Lever == 3)
    {
        throw new WebException("get status.");
    }
}

With the following.

public class StatusResponse
{
    public int Total { get; set; }
    public int Goal { get; set; }
}

Then catching this in the client as per

try
{
    var postResponse = client.Post<StatusResponse>("status", new StatusRequest { Date = DateTime.Now, Lever = 3 });
    Console.WriteLine("{0} of {1} achieved", postResponse.Total, postResponse.Goal);
}
catch (WebServiceException wse)
{
    // At this point wse.ResponseStatus field is valid and filled in.
}
1

1 Answers

1
votes

If you want to use the {RequestDto}Response convention and also ensure a ResponseStatus is returned you have to opt-in and add it to the Response DTO, e.g:

public class StatusResponse
{
    public int Total { get; set; }
    public int Goal { get; set; }

    public ResponseStatus ResponseStatus { get; set; }
}

This is because there is an explicit exception for Responses that follow the convention {RequestDto}Response naming convention:

If it exists:

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. (If you have decorated the {ResponseDto}Response class and properties with [DataContract]/[DataMember] attributes, then ResponseStatus also needs to be decorated, to get populated).

Otherwise, if it doesn't:

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.