restsharp / restsharp Goto Github PK
View Code? Open in Web Editor NEWSimple REST and HTTP API Client for .NET
Home Page: https://restsharp.dev
License: Apache License 2.0
Simple REST and HTTP API Client for .NET
Home Page: https://restsharp.dev
License: Apache License 2.0
I had a quick look and didn't see any references to support for this. OAuth is multi-legged in terms of setup, but once you have the right credentials at the client side you can send over as headers in a similar way to basic authentication. There are OAuth samples for .NET at http://oauth.net/code/ but I think they make the protocol feel overly complicated.
I would use for a Yammer API client I am building, maybe I will get some time to hack this up for inclusion in RestSharp.
get and post method behaves same but if its delete it behaves diffferently.
var client = new RestClient("https://graph.facebook.com");
var request = new RestRequest("/me", Method.POST);
var response = client.Execute(request);
or if i do
var request = new RestRequest("/me", Method.GET);
the request url become https://graph.facebook.com/me
but if the method is delete
var request = new RestRequest("/me", Method.DELETE);
it becomes https://graph.facebook/com//me
notice the double / before me
temporarily i fixed in my code when doing delete, but i think it should be in restsharp unless thats the expected behavior.
string graphPath = "/me";
if (graphPath.StartsWith("/") && graphPath.Length > 1)
graphPath = graphPath.Substring(1);
var request = new RestRequest(graphPath, Method.DELETE);
coz this will allow to create consisted api
facebook.Get("/me");
faecbook.Post("/me/feed","some message");
facebook.Delete("/id");
Issue to do with the Magic name matching when dealing with lists
Example: http://api.eventful.com/docs/venues/search
In this case the Venues/Venue list
Call RestClient on a HTML Page (the RestRequest should have it's RequestFormat set to DataFormat.Xml) and you get an exception.
Proposed fix in RestClient.Execute:
try
{
response.Data = handler.Deserialize(raw);
}
catch
{
response.ResponseStatus = ResponseStatus.Error;
response.Data = default(T);
}
A trailing / causes problems with certain third-party API's. The following change resolves the problem.
Line 147 in RestClient.cs
return string.IsNullOrEmpty(assembled) ? new Uri(BaseUrl) : new Uri(string.Format("{0}/{1}", BaseUrl, assembled));
Newtonsoft.Json.Silverlight.dll is 264k at the momemnt, espcially saving that space for web based apps would be really great improvement.
but mite require lot of change in the current restsharp codes.
it would really be good if restsharp was under 100k including dependencies :-)
Not sure if this possible or not, just putting it here so I can investigate it.
When deserializing from both XML and JSON if the target property is nullable and the data value is null make sure to set the property to null (if that isn't the default). If not and there's a value, set it. If there's a value and it can't be deserialized, set property to null (if that isn't the default).
Seems like the Async methods don't append the RestSharp parameters.
After looking at Sync and Async methods i found out that you forogt to add
var url = AssembleUrl();
in private void GetStyleMethodInternalAsync(string method, Action callback) method (Http.Async.cs file)
it should be like this.
var url = AssembleUrl();
var webRequest = ConfigureAsyncWebRequest(method, url);
then it works.
just checked it for get, not sure about post and delete methods, in case i come up with some bugs i will inform it.
First, I'm not sure if this is a bug or user error. I am trying to deserialize the sample json below by calling _restClient.Execute<List<User>>(request). I have tried setting the RootElement to "data" or leaving it blank. Every time it dies on JArray.Parse(response.Content). As a workaround, I am parsing the json using JObject.Parse, but it would be much cleaner to use the built in deserializing capabilities of RestSharp.
Sample data (from Facebook Graph API - Friend List)
{"data":[
{"name":"Bob","id":"12345"},
{"name":"Mike","id":"123456"},
{"name":"Joe","id":"100000000000"}
]}
My poco:
public class User
{
public string Id { get; set; }
public string Name { get; set; }
}
I get this error trying to add a reference to json.net in my windows phone 7 project. Is there a way around this or will I be unable to use the json deserializer?
"...was not built with the windows phone runtime.Windows phone projects will only work with windows phone assemblies."
I'm doing this:
var client = new RestClient();
client.BaseUrl = "http://api.gowalla.com";
client.Authenticator =
new HttpBasicAuthenticator("username", "password");
But when I execute the request, the service asks me to login. I've looked at the headers that are sent using Fiddler and I can't see any authentication headers. Also, I cannot find any AppendHeaders() call in Http.GetStyleMethodInternalAsync().
Am I missing something or has this not been implemented?
Unfortunately, this makes Restsharp useless for me since I need authentication. However, it seems like a very nice library, keep up the good work!
I am trying to deserialize a the json:
"types": [ "locality", "political" ]
Into a List. Attempting to do so throws - System.MissingMethodException: No parameterless constructor defined for this object.
Not sure if this is a bug or I am just doing it wrong.
If i set the compilation to Release configuration the solution doesn't compile.
its coz their is no conditional compilation symbol for release configuration "FRAMEWORK"
any ways do u support pull request and merge? that might make your work easier.
Hi John,
JSON support isn't on par with the XML support. If an array is returned from a remote web service, then the library will crash in JsonDeserializer.cs.
This can be easily demonstrated by connecting to the Twitter REST API and appending ".json" instead of ".xml" to the service address.
Basically it boils down to JObject [JSON.NET] does not support Arrays, and JArray.Parse should be used instead. This brings up another issue -- the JSON deserializer does not know how to handle more than a single record.
When a new instance of Guid is created with an empty string, instead of sending back Guid.Empty it tries to initialize new Guid("") which causes an exception.
If the element name is not the property name then a match will not be found. For example (using Google Weather api):
Works:
public Current_Conditions Current_Conditions { get; set; }
Also works:
public CurrentConditions Current_Conditions { get; set; }
But this won't:
public Current_Conditions Conditions { get; set; }
This makes it diffulcult to have an interface for various weather services. Using an attribute allows the following:
``[ElementName("Current_Conditions")]
public Conditions CurrentConditions { get; set; }
The attribute class:
``///
/// Specifies the name of the element associated with a class property when the class name does not match he xml element name
/// </summary>
public class ElementNameAttribute : System.Attribute
{
/// <summary>
/// The name of the XML element tied to this class property
/// </summary>
public string Name { get; set; }
/// <summary>
/// The name of the element in the XML document
/// </summary>
/// <param name="name"></param>
public ElementNameAttribute(string name)
{
Name = name;
}
}
And the updated markup in RestSharp.Deserializers:
XName name; var atts = prop.GetCustomAttributes(typeof(ElementNameAttribute), true); if (atts.Length > 0) { name = ((ElementNameAttribute)atts[0]).Name.AsNamespaced(Namespace); } else { name = prop.Name.AsNamespaced(Namespace); }
XmlDeserializer doesnt match inline lists.
By inline lists I mean when an element contains a list of certain elements as well as elements not part of the list
(from Google weather API)
<forecast_information />
<current_conditions />
<forecast_conditions />
<forecast_conditions />
<forecast_conditions />
When using a response class that inherits a List the elements in the list are matched on the class name (as there is no real variable name) this name is case sensitive.
I'd fix this but i dont have Git install on this computer. Probably when i get home so im just adding this to remind me.
Code: In XmlDeserialiser.cs
HandleListDerivative() where it calls root.Descendants()
Just realized I checked in incomplete code for file uploads. Will fix soon!
I am trying to deserialize this json (from Twitters get friend ids api):
[14877833,13434092,88344083]
The result is a list of 3 longs all with the value of 0. If I try to get as a List, it returns null.
ExecuteCallback should be invoked in ResponseCallback when an exception is caught so that the response gets passed back.
I have a couple of private API's I work with from some startups I to dev for that reply heavily on the Accept header and both have failed due to the use of the semicolon to separate the content types in the Accept header (they are expecting a comma).
I don't really know which way is right. However, referring to http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html it seems that the comma is used to separate the content types and semicolon is used to separate a qualifier from it's associated content type.
I think its a good idea to expose ParseUrlQueryString also, especailly when dealing with OAuth2.
they return results in.
https://graph.facebook.com/1237476932/feed?limit=25&oauth_token=1314033135-100001241534829%7C1237417Cq_Jgbyd1L87YiLi-ZAfyFo.&until=2010-07-12T09%3A53%3A41%2B0000
so extracting appropriate querystring would be helpful if restsharp already contains this method.
desktop supports public static NameValueCollection ParseQueryString(string query) from HttpUtility class but silverlight doesn't. it then becomes problem of writing custom method for silverlight. another problem with silverlight is that it doesn't support the class NameValueCollection.
after checking the QueryString in silverlight it seems to rather return IDictionary<string,string> which i think is pretty reasonable. so mite be Restsharp can have a function called
public static IDictionary<string,string> ParseQueryString(string query)
so that it works in both desktop and silverlight using the same api.
or if it wants to mimic the feature of NameValueCollection IDictionary<string,string[]> or IDictionary<string,List> might be appropriate.
anyways heres the code, did a slight change from the mono HttpUtility code.
public static IDictionary<string, List> ParseQueryString(string query)
{
var result = new Dictionary<string, List>();
if (string.IsNullOrEmpty(query))
return result;
string decoded = HtmlDecode(query);
int decodedLength = decoded.Length;
int namePos = 0;
bool first = true;
while (namePos <= decodedLength)
{
int valuePos = -1, valueEnd = -1;
for (int q = namePos; q < decodedLength; q++)
{
if (valuePos == -1 && decoded[q] == '=')
{
valuePos = q + 1;
}
else if (decoded[q] == '&')
{
valueEnd = q;
break;
}
}
if (first)
{
first = false;
if (decoded[namePos] == '?')
namePos++;
}
string name, value;
if (valuePos == -1)
{
name = null;
valuePos = namePos;
}
else
{
name = UrlDecode(decoded.Substring(namePos, valuePos - namePos - 1));
}
if (valueEnd < 0)
{
namePos = -1;
valueEnd = decoded.Length;
}
else
{
namePos = valueEnd + 1;
}
value = UrlDecode(decoded.Substring(valuePos, valueEnd - valuePos));
if (name != null)
{
if (result.ContainsKey(name))
result["name"].Add(value);
else
result.Add(name, new List<string> { value });
}
if (namePos == -1)
break;
}
return result;
}
I think it would be great if RestSharp could remove dependency from HttpUtitlity so that it works with client profiles.
i found a link here for it: http://www.dotnetmonster.com/Uwe/Forum.aspx/dotnet-compact-framework/3530/UrlEncode-UrlDecode
seems to work for .net compact framework too. havent tested this thou.
a proper fix with formating can be found here http://github.com/prabirshrestha/FacebookSharp/blob/master/src/FacebookSharp.Core/FacebookUtils/HttpUtitliy.cs
reason 1: it will work in partial trust
reason 2: NetworkCredential always performs two calls to a REST endpoint to handshake basic auth... which means it doubles the traffic needlessly... also it breaks some twitter behaviors
Setting BasicAuth header yourself in request headers is 100% faster
To test it, hit an API with NetworkCredential and run Wireshark, you'll first see a 401, then a 200
Add the ability to do something like (maybe via a different execute method or something)
dynamic response = _restClient.Execute(request);
And the return value would be a dynamic ExpandoObject populated with all the values.
Having some trouble matching elements such as:
<geo:point>
<geo:lat>50.7</geo:lat>
<geo:long>-3.5333333</geo:long>
</geo:point>
It would be nice to see some information about the Request in the Response, at the minimum it should contain the exact URL that was called. That's helpful when working with Parameters.
The RestRequest object contains information about the Request before the call, but it does not specify what exactly was sent to the server as that is processed further down the pipeline.
Ideally I would like to see almost RAW HTML, but at least the exact URL and all Header fields.
Handle dashes in names like already handling underscores in names.
Entering this for tracking purposes as I'm working on a fix right now.
When using a single AsyncRestClient for multiple Requests and calling BeginExecute with different T's, then calling EndExecute will throw NullReferenceExceptions. The reason is that the genericCallback member variable is overwritten and the cast in EndExecute will fail.
This does not occur when passing in a Callback to BeginExecute, casting AsyncDelegate to RequestExecuteCaller and calling EndInvoke on it as this doesn't even call EndExecute I think.
private void button3_Click(object sender, EventArgs e)
{
string url = "http://localhost:8080";
var client = new AsyncRestClient(url);
var cbs = new List<IAsyncResult>();
for (int i = 0; i < 10; i++)
{
var req = new RestRequest("add", Method.PUT);
var par = new Parameter
{
Name = "ValueToAdd",
Type = ParameterType.HttpHeader,
Value = i
};
req.AddParameter(par);
if (i % 2 == 0)
{
var res = client.BeginExecute<RespA>(req, null, null);
cbs.Add(res);
}
else
{
var res = client.BeginExecute<RespB>(req, null, null);
cbs.Add(res);
}
}
for (int i = 0; i < 10; i++)
{
var res = cbs[i];
if (i%2 == 0)
{
// NullReferenceException as genericCallback is RequestExecuteCaller<RespB>
var rest = client.EndExecute<RespA>(res);
}
else
{
var rest = client.EndExecute<RespB>(res);
}
}
}
Headers and possibly cookies are not added to async requests.
the following returns a status code 411. perhaps i'm not using PUTs right. resource 'profile' identified by id in userinfo.Data.id is being called with the instance method 'update_last_login'.. No parameters are necessary since timestamp comes from the server.
request = new RestRequest();
client.BaseUrl = "http://xxx.xxxxxx.coml";
request.Method = Method.PUT;
request.Resource = "profiles/" + userinfo.Data.id + "/update_last_login";
var result = client.Execute(request);
A trailing / causes problems with certain third-party API's. The following change resolves the problem.
Line 147 in RestClient.cs
return string.IsNullOrEmpty(assembled) ? new Uri(string.Format("{0}/{1}", BaseUrl, assembled)) : new Uri(BaseUrl);
Not sure if it currently works or not, just creating this so I remember to check later.
Http.GetStyleMethodInternalAsync does not catch exceptions thrown by webRequest.BeginGetResponse. These exceptions should be caught, the correct response should be set and passed into the callback.
I can specify the User-agent by manually adding a Header, but maybe it should be exposed as a property on the RestClient or the RestRequest (or even on both, with the Client serving as a "global" one and the Request being able to override it on a single request).
This should emphasize the importance of it, I'm even thinking of making it mandatory to specify one in my branch. As a server operator, the User-Agent is really helpful, especially when deciding whether or not to ban a client making too many requests.
Allow for changing root elements in xml responses.
Mainly for errors where some restful services use <error .../> instead of the regular <response .../> or what ever the service use.
i think it would be good if it exposes some HttpUtility methods for silverlight. such as
public static string HtmlAttributeEncode(string s)
public static string HtmlDecode(string s)
public static string HtmlEncode(string s)
public static string UrlDecode(string str)
public static string UrlEncode(string str)
so that we can write using restsharp's HttpUtiltily function rather than having conditional symbols in our code. (restsharp auto handles the conditional symbol would be great).
just my opinion.
If you are just trying to access the RestClient's BaseUrl (eg no .Resource set on the request), RestClient.BuildUri throws a null reference exception on this line:
if (assembled.StartsWith("/"))
If .Resource isn't set, it should probably assume I want to request /.
It looks like RestSharp requires a specialized list class in order to deserialize collections. E.g. I have to do like this:
public class MyObjectCollection : List<MyObject>
{
}
client.ExecuteAsync<MyObjectCollection>(new RestSharp.RestRequest("/"), DataReceived);
instead of just:
client.ExecuteAsync<List<MyObject>>(new RestSharp.RestRequest("/"), DataReceived);
With the generic list it breaks in XmlDeserializer.cs at line 179
var t = type.BaseType.GetGenericArguments()[0];
...since the base type is System.Object.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.