5

I am using ServiceStack to create a C# client to a JSON RESTful service. I have this code that returns my DTO:

Search result = restClient.Get (search);

This works fine, but in order to effectively debug the search results coming back I need to output the text content from the underlying HTTP Response object. (I don't know all the elements in the response yet in order to add them to the DTO).

Is there any way I can get hold of the underlying HTTP response, and thus the full text content, from my result object?

Thanks in advance. @adamfowleruk

adamfowleruk
  • 257
  • 2
  • 10

4 Answers4

8

When inheriting from ServiceStack's built-in Service you can access the underlying Request and Response directly from the Response class with:

public class MyService : Service 
{
    public object Get(Request request)
    {
        base.Request ...
        base.Response ...
    }
}

You won't see the response output in your service or filters since it writes directly to the response stream and is the last thing that ServiceStack does after executing your service and all response filters.

For diagnosing HTTP I recommend using Fiddler or WebInspector also ServiceStack's built-in Request Logger might help as well.

Consuming a ServiceStack service

If you're using the C# Service Clients you can simply ask for what you want, e.g. you can access the returned response as a raw string:

string responseJson = client.Get<string>("/poco/World");

Or as raw bytes:

byte[] responseBytes = client.Get<byte[]>("/poco/World");

Or as a Stream:

using (Stream responseStream = client.Get<Stream>("/poco/World")) {
    var dto = responseStream.ReadFully().FromUtf8Bytes().FromJson<PocoResponse>();
}

Or even access the populated HttpWebResponse object:

HttpWebResponse webResponse = client.Get<HttpWebResponse>("/poco/World");

webResponse.Headers["X-Response"] //World
using (webResponse)
using (var stream = webResponse.GetResponseStream())
using (var sr = new StreamReader(stream)) {
    string response = sr.ReadToEnd();
}

You can also introspect the HttpWebResponse by using Global and Local Response filters, e.g:

JsonServiceClient.HttpWebResponseFilter = httpRes => { .. };

Or using a Local filter:

var client = new JsonServiceClient(baseUrl) { 
    ResponseFilter = httpRes => { .. }
};

Consuming a 3rd Party Service

If you're consuming a 3rd Party REST/HTTP API you can use a responseFilter: in ServiceStack's HTTP Util extensions:

List<GithubRepo> repos = "https://api.github.com/users/{0}/repos".Fmt(user)
    .GetJsonFromUrl(responseFilter: httpRes => {
        var remaining = httpRes.Headers["X-Api-Remaining"];
    })
    .FromJson<List<GithubRepo>>();
mythz
  • 141,670
  • 29
  • 246
  • 390
  • Thanks, but I'm not creating a service - I'm consuming one. How do I get a Response object when all I get back from Get() is a DTO? – adamfowleruk Mar 22 '13 at 22:08
  • 1
    Get or Post is very useful for debugging. First I make a call with those methods then use DataContract and DataMember attributes on DTO classes based on the response I get. It is very cool. – Ufuk Hacıoğulları Mar 22 '13 at 22:32
  • Thanks for all your help. Managed to figure out a good way to do it. – adamfowleruk Mar 23 '13 at 14:54
  • +1 for client.Get("/poco/World"); This helped me overcome the problem of bypassing the deserializer on the client side and get access to the raw response, allowing me to inspect the headers, and pass a 'length' of a stream being downloaded. Now I can do client-side download progress bars. Yay – Chris Ray Oct 08 '13 at 14:41
3

I use Fiddler to debug my services. It gives you all sorts of cool HTTP debugging facilities.

http://www.fiddler2.com/fiddler2/

rossipedia
  • 56,800
  • 10
  • 90
  • 93
3

I like to use RestConsole. It is a Chrome Extension and you can easily submit POST requests and see the response. It is also handy to create sample data and then step into the ServiceStack code and see what's happening. The ServiceStack PluralSight course has a nice demo of how to use them together.

robrtc
  • 2,747
  • 1
  • 17
  • 22
2

Thanks to the above help I found the right answer. Documenting here for others:-

  SearchResponse result = null; // my ServiceStack DTO

  HttpWebResponse webResponse = restClient.Get<HttpWebResponse>(
    completePath("/v1/search",qp)); // builds the URL with parameters

  using (var stream = webResponse.GetResponseStream())
  using (var sr = new StreamReader(stream)) {
    var text = sr.ReadToEnd();
    log.log ("response text: " + text); // *** PRINTING STRING VALUE HERE FOR DEBUG 
    result = text.FromJson<SearchResponse>();
  }

  // Now do something useful with the result DTO object

  log.log ("RESULT: " + result.ToString ());
  for (int i = 0; i < result.Results.Length; i++) {
    log.log ("Result " + i + ": " + result.Results[i].ToString());
  }
adamfowleruk
  • 257
  • 2
  • 10