Considering adding support for dynamic in a .NET 4 version of RestSharp. What do you think?

1,294 views
Skip to first unread message

John Sheehan

unread,
Apr 17, 2012, 8:14:52 PM4/17/12
to rest...@googlegroups.com
public static partial class RestClientExtensions
{
public static RestResponse<dynamic> ExecuteDynamic(this IRestClient client, IRestRequest request)
{
var response = client.Execute(request);

var generic = (RestResponse<dynamic>)response;
dynamic content = SimpleJson.DeserializeObject(response.Content);
generic.Data = content;

return generic;
}
}

prabir

unread,
Apr 17, 2012, 9:01:22 PM4/17/12
to rest...@googlegroups.com
I don't think RestSharp needs to introduce new method. Why don't you just make it work for client.Execute<dynamic> or client.Execute<object>

Here is how you would do for strongly typed currently.

            var client = new RestClient("https://graph.facebook.com");
            var result = client.Execute<User>(new RestRequest("4"));
            var user = result.Data;
            string name = user.name;
            string id = user.id;

So make it dynamic if T == typeof(object) and response.content-type == "application/json", 

In simple json if you pass <T> as System.Object or dynamic, it will just create either jsonobject/jsonarry/bool/long/string and other primitive types. So you can use dynamic.

            string json = "{\"id\":\"4\",\"name\":\"Mark Zuckerberg\",\"first_name\":\"Mark\",\"last_name\":\"Zuckerberg\",\"link\":\"http:\\/\\/www.facebook.com\\/zuck\",\"username\":\"zuck\",\"gender\":\"male\",\"locale\":\"en_US\"}";
            var stronglyTypeObject = SimpleJson.DeserializeObject<User>(json);
            var stornglyTypedName = stronglyTypeObject.name;
 
            dynamic dynamicObject = SimpleJson.DeserializeObject<dynamic>(json);
            var dynamicObjectName = dynamicObject.name;
 
            dynamic jsonObject = SimpleJson.DeserializeObject<JsonObject>(json);
            var josnObjectName = jsonObject.name;
 
            dynamic obj = SimpleJson.DeserializeObject<object>(json);
            var objName = obj.name;

and .net 3.5/wp7 users where dynamic is not supported can still continue to use Execute<object> but instead of dynamic since it returns JsonObject/JsonArray so you will have to cast it to IDictionary<string,object> or IList<object>

            var dict = SimpleJson.DeserializeObject<object>(jsonas IDictionary<stringobject>;
            var dictName = obj["name"];

Nathan Totten has a blog about this on how we solve the dynamic craziness in various .net platforms/versions in Facebook C# SDK http://blog.ntotten.com/2010/09/07/dynamic-objects-and-the-facebook-c-sdk/

Here is some extra points on how we deal with FB C# SDK. 

By default when you install SimpleJson from nuget, JsonArray and JsonObject classes are public but hidden from intellisense using [EditorBrowsable(EditorBrowsableState.Never)]. These two classes are the main feature that allows you to have dynamic. You need to define SIMPLE_JSON_DYNAMIC conditional symbol though. If you use the default json serializer provided by the FB C# SDK which is SimpleJson you get dynamic support out of the box. But if you want to use other json serializers such as json.net we provide a wrapper which converts JArray to JsonArray and JObject to JsonObject. Full code can be found at https://github.com/facebook-csharp-sdk/facebook-csharp-sdk/blob/a914df1c49cd1bfb8eff337afc7beb1d07f12260/Build/NuGet/Facebook/serializers/JsonNetSerializer.cs

In the end this will look better for those that support dynamic.

            var client = new RestClient("https://graph.facebook.com");
            var result = client.Execute<dynamic>(new RestRequest("4"));
            var user = result.Data;
            string name = user.name;
            string id = user.id;

And for those unlucky .net 3.5 and wp7 devs where dynamic is not supported you still partially benefit from it.

            var client = new RestClient("https://graph.facebook.com");
            var result = client.Execute<object>(new RestRequest("4"));
            var user = (IDictionary<stringobject>)result.Data;
            var name = (string)user["name"];
            var id = (string)user["user"];

Cecil

unread,
Apr 18, 2012, 2:00:08 AM4/18/12
to rest...@googlegroups.com
I agree with @prabir 

John Sheehan

unread,
Apr 18, 2012, 6:54:31 PM4/18/12
to rest...@googlegroups.com
I'd prefer to do this without modifying any of the current
deserializer code. That's just more #if def hell I don't want to
maintain. So while I agree with you that would be the ideal API, it's
not going to happen in the current RestSharp.

prabir

unread,
Apr 18, 2012, 9:32:30 PM4/18/12
to rest...@googlegroups.com
You don't need to define any #if def, all the work is already done by SimpleJson.cs. The only thing you need is to to define SIMPLE_JSON_DYNAMIC as conditional symbol.

Execute<dynamic> == Execute<object> so typeof(T) == typeof(object) will be true for both Execute<dynamic> and Execute<object>. so that means no #if def

And as for json.net's JArray to JsonArray and JObject to JsonObject is also optional. If you don't want to support conversion, then it is great too. I think SimpleJson is more then enough. The only reason we did this in fb c# sdk was lots of users were using strongly typed with json.net features and json.net did not implement the dynamic we wanted it too. This was almost a year back not sure if its fixed in json.net now. 

John Sheehan

unread,
Apr 26, 2012, 1:44:06 AM4/26/12
to rest...@googlegroups.com
ExecuteDynamic(request) is in  https://nuget.org/packages/RestSharp/103.1.0-beta 

Please test and let me know what you think.

Victor Gladkikh

unread,
Jun 26, 2012, 6:50:52 AM6/26/12
to rest...@googlegroups.com
It fails for me 

Unhandled Exception: System.InvalidCastException: Unable to cast object of type 'RestSharp.RestResponse' to type 'RestSharp.RestResponse`1[System.Object]'.
   at RestSharp.RestClientExtensions.ExecuteDynamic(IRestClient client, IRestRequest request)

Todd Menier

unread,
Sep 7, 2012, 3:31:10 PM9/7/12
to rest...@googlegroups.com
Same here. Others are having the same issue (here and here). Is this a bug or we doing something wrong?

Andrew Young

unread,
Sep 8, 2012, 3:12:16 AM9/8/12
to rest...@googlegroups.com
Are you looking for support for dynamic objects? The links you reference look like they can be solved with generics.

-- 
Andrew Young
Sent with Sparrow

Reply all
Reply to author
Forward
0 new messages