Handling responses of different types based on status code

5,223 views
Skip to first unread message

jonnii

unread,
Mar 22, 2012, 9:45:25 AM3/22/12
to RestSharp
Hi,

I have an end point that creates resources and on success it will
return an object with the new ID and other data, while on failure it
will return a list of validation messages. My RestSharp code looks
like the examples, but I end up having to do something like this:

var response = RestClient.Execute<T>(request);

if(response.StatusCode == HttpStatusCode.BadRequest)
{
var errors =
JsonConvert.DeserializeObject<List<ValidationError>>(response.Content);
.. do something with errors ..
}

In my opinion there's a few things wrong with this, but the biggest is
that I'm explicitly deserializing the content as json (when it could
very well be xml).

I'm wondering what the best way to handle this is?

I can think of a few ways rest sharp could be extended to support this
scenario, for example:

response.DeserializeAs<List<ValidationError>>();

Thoughts?

- jonnii

jonnii

unread,
Mar 22, 2012, 11:05:28 AM3/22/12
to RestSharp
It looks like another alternative is to do something like this:

var response = RestClient.Execute(request);

if(response.StatusCode == HttpStatusCode.BadRequest)
{
var validationErrorResponse = (RestResponse<List<ValidationError>>)
response;
... do something ...
}

var expectedResponse = (RestResponse<Something>) response;
return expectedResponse.Data;

This took me a while to find, because the cast to RestResponse<T> is
explicit, but thankfully there's a way to get the right response type
out using the content-types.

jonnii

unread,
Mar 22, 2012, 11:16:04 AM3/22/12
to RestSharp
Actually, I spoke to soon, that doesn't work.

Cristovão Morgado

unread,
Mar 22, 2012, 11:28:51 AM3/22/12
to rest...@googlegroups.com
I Usually do this:


 client.ExecuteAsync(rq, (response, async) =>
                    {
                        Debug.WriteLine(response.Content);
                        if (response.StatusCode == HttpStatusCode.OK)
                        {
                            if (Register)
                            {
                                var result = JsonConvert.DeserializeObject<Model.PushRegistrationResponse>(response.Content);
                                success(result.Registered);
                            }
                            else
                            {
                                var result = JsonConvert.DeserializeObject<Model.PushUnRegistrationResponse>(response.Content);
                                success(result.Unregistered);
                            }
                        
                        }
                        else
                        {

   var result = JsonConvert.DeserializeObject<Model.PushRegistrationResponseERROR>(response.Content);
                            failure(result);
                        }                     });
--
Cristovao Morgado
@TheSaintr


Andy Cutright

unread,
Mar 22, 2012, 11:37:06 AM3/22/12
to rest...@googlegroups.com
@jonnii There's a hook to support deserializing objects of different types. You can determine the respons status code & change what type should be deseralized. I've not worked with this yet, I just ran into the same sort of problem, and am trying to work it out (as a side line). 


Frankly, I don't see why the library doesn't accept a dictionary mapping status codes to deserialization types. 

@cristavo, how's the performance of the JsonConvertDeserializeObject? 

Cheers,
Andy 

Cristovão Morgado

unread,
Mar 22, 2012, 11:38:02 AM3/22/12
to rest...@googlegroups.com
JsonConvertDeserializeObject  ... is already used by RestSharp :) being part of JSON.NET ;)
--
Cristovao Morgado
@TheSaintr


Andy Cutright

unread,
Mar 22, 2012, 11:42:15 AM3/22/12
to rest...@googlegroups.com
Thanks Cristavão :) 

jonnii

unread,
Mar 22, 2012, 1:25:32 PM3/22/12
to RestSharp
I really want the API to look like this:

var client = new RestClient("http://localhost:10013/api");

var person = new Person("abcd");

var request = client
.CreateRequest("people/{id}", new { id = person.Id })
.Content(person);

var response = client.Post(request);

response.On(HttpStatusCode.BadRequest, (ValidationErrors e) =>
{
throw new Exception("omg validation errors");
});

var summary =
response.On(HttpStatusCode.Created).UnWrap<PersonSummary>();

@Cristovão: Your example requires the response to be json, what if
it's xml?

On Mar 22, 11:42 am, Andy Cutright <r.d.c0...@gmail.com> wrote:
> Thanks Cristavão :)
>
> On Thu, Mar 22, 2012 at 8:38 AM, Cristovão Morgado <
>
>
>
>
>
>
>
> cristovao.morg...@gmail.com> wrote:
> > JsonConvertDeserializeObject  ... is already used by RestSharp :) being
> > part of JSON.NET ;)
>

Cristovão Morgado

unread,
Mar 22, 2012, 1:34:15 PM3/22/12
to rest...@googlegroups.com
Just change the deserializer...
the "secret" is to use the response.content  (it's a string) and deserialize it as whatever you want...
--
Cristovao Morgado
@TheSaintr


jonnii

unread,
Mar 22, 2012, 1:36:50 PM3/22/12
to RestSharp
I understand that, but it's a shame I can't ask restsharp to
deserialize the content for me once I know what the type is, it means
I have to go out to json.net myself and/or switch on the content-type.

On Mar 22, 1:34 pm, Cristovão Morgado <cristovao.morg...@gmail.com>
wrote:

Cristovão Morgado

unread,
Mar 22, 2012, 1:39:10 PM3/22/12
to rest...@googlegroups.com
JSON.NET is already bundled with RestSharp...
--
Cristovao Morgado
@TheSaintr


jonnii

unread,
Mar 22, 2012, 2:42:16 PM3/22/12
to RestSharp
I know, but it's still not ideal. Why do I have to know the response
is json?

On Mar 22, 1:39 pm, Cristovão Morgado <cristovao.morg...@gmail.com>

John Sheehan

unread,
Apr 3, 2012, 1:24:42 AM4/3/12
to rest...@googlegroups.com
I agree this is not ideal, if someone wants to implement this, I'm happy to discuss getting it merged in. It needs to be 100% backwards compatible though.

Something like

client.Execute....<T>(200, response = > { ... } );

Fill in the dots with something descriptive. I can't think of anything at the moment.
Reply all
Reply to author
Forward
0 new messages