How to parse JSON using RestSharp? - c#

var client = new RestClient("http://10.0.2.2:50670/api");
var request = new RestRequest("Inventory", Method.GET);
request.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; };
// execute the request to return a list of InventoryItem
RestResponse<JavaList<InventoryItem>> response = (RestResponse<JavaList<InventoryItem>>)client.Execute<JavaList<InventoryItem>>(request);
The content returned is a JSON string, an array of objects. The following is a short excerpt of it:
[{"Id":1,"Upc":"1234567890","Quantity":100,"Created":"2012-01-01T00:00:00","Category":"Tequila","TransactionType":"Audit","MetaData":"PATRON 750ML"},{"Id":2,"Upc":"2345678901","Quantity":110,"Created":"2012-01-01T00:00:00","Category":"Whiskey","TransactionType":"Audit","MetaData":"JACK DANIELS 750ML"},{"Id":3,"Upc":"3456789012","Quantity":150,"Created":"2012-01-01T00:00:00","Category":"Vodka","TransactionType":"Audit","MetaData":"ABSOLUT 750ml"}]
The error message:
Operation is not valid due to the current state of the object
What is wrong here? My InventoryItem has the same properties as each object in the JSON string. Am I missing a step?

I suspect that SimpleJson, used in RestSharp can't deserialise to a JavaList.
First I would try deserialising to a:
List<InventoryItem>
Failing that, I recommend ServiceStack.Text - .Net's fastest JSON library; and do:
var response = client.Execute(request);
var thingYouWant = JsonSerializer.DeserializeFromString<List<InventoryItem>>(response.Content);
This is actually what I do myself.
Edit (Thank you to commentators):
In newer versions this would now be:
var deserializer = new JsonDeserializer();
deserializer.Deserialize<List<InventoryItem>>(response);

Failing w/ auto-magic casting, I use this in a pinch:
var rc = new RestClient("https://api-ssl.bitly.com");
var rr = new RestRequest("/v3/link/clicks?access_token={access_token}&link={bitlyUrl}", Method.GET);
rr.AddUrlSegment("bitlyUrl", bitlyUrl);
rr.AddUrlSegment("access_token", BityAccessToken);
var response = rc.Execute(rr);
dynamic json = Newtonsoft.Json.Linq.JObject.Parse(response.Content);
var clicks = Convert.ToInt32(json.data.link_clicks.Value);

Related

.NET 6 : HttpClient work with dynamic json response

I'm using .NET 6. How work with json response from HttpClient without declaring a type?
I try do request with dynamic:
var http = new HttpClient();
var res = await http.GetAsync("https://api");
var body = await res.Content.ReadFromJsonAsync<dynamic>();
In debug mode I see that I get the correct value:
but then I try get access to field, I get an error
body['pagesCount']
Try following code
var resultType = new { refresh_task = "" }.GetType();
dynamic? result = await response.Content.ReadFromJsonAsync(resultType);

Move Json Object From One Site To Another

I have two project in asp.net webforms with different url. I need to move c# object from one to the other. I tried to serialize it to JSON with JavaScriptSerializer and move it as parameter in the url, but I don't want the client would see the json
A a = new A()
{
val = 1,
val1 = "very long string"
};
var jsonSerialiser = new JavaScriptSerializer();
string data = jsonSerialiser.Serialize(a);
Response.Redirect(service.RedirectToCheckout("http://localhost:44316/PageOnOtherSite.aspx?data=" + data));
Any ideas?
simple post request using HttpClient
using(var client = new HttpClient())
{
response = await httpClient.PostAsync(uri, new StringContent(data));
{

RestSharp get serialized output

I am looking for a way to access the serialized result of the AddBody call.
I am using the built in RestSharp Serializer.
Example:
class Foo
{
public string FooField;
}
void SendRecord()
{
var f = new Foo();
f.FooField = "My Value";
request.AddBody(f);
// How do I get the serialized json result of the add body call without
// data? I would like to log the serialized output of the add body call to
// the database.
//Expected {"FooField":"My Value"}
var response = client.Execute(request);
}
I figured it out by finding this post.
request.Parameters.Where(p => p.Type == ParameterType.RequestBody).FirstOrDefault();
I also struggled with this (using v107 preview) and couldn't find any examples of logging the actual string sent to the server. The issue I was trying to debug was getting the right serialisation settings so the object was no use to me.
The only way I could find to get the serialized body as a string was to hook into the OnBeforeRequest event on the RestRequest:
var request = new RestRequest("/", Method.Post)
.AddHeader(KnownHeaders.ContentType, "application/json", false)
.AddJsonBody(myObj);
request.OnBeforeRequest = async (httpRequest) =>
{
var requestBodyStr = await httpRequest.Content.ReadAsStringAsync();
Trace.WriteLine($"Request body: {requestBodyStr}");
};
RestSharp itself doesn't expose the serialized request body when you pass an object to it.
There is a way to get at it though, I just posted over here:
https://stackoverflow.com/a/75537611/2509281
Right off the RestSharp homepage (http://restsharp.org/):
// execute the request
RestResponse response = client.Execute(request);
var content = response.Content; // raw content as string <~~~~~~~~~~

Parameter count mismatch error in RestSharp?

public IRestResult Send(MessageEnvelope envelope)
{
var request = new RestRequest(Method.POST);
request.AddBody(envelope);
request.RequestFormat = DataFormat.Json;
var responce = _restClient.Execute(request);
return new RestResult
{
Success = responce.StatusCode == HttpStatusCode.OK,
ErrorMessage = responce.Content
};
}
When I pass the envelpoe value I had a runtime error call
Parameter count mismatch
in the line containing request.AddBody(envelope);.
(when I add values to AddBody method).
How can I fix this?
Our solution was to replace the default serializer with JSON .NET
I used the instructions here:
https://github.com/restsharp/RestSharp/blob/master/readme.txt
However, you now have to set the serializer on the request and not at the client.
// Use JSON .NET serializer
request.JsonSerializer = new JsonSerializer();

Moving from standard .NET rest to RestSharp

For the most part, I have managed quite quickly to move my code from standard .NET code to using RestSharp. This has been simple enough for GET processes, but I'm stumped for POST processes
Consider the following
var request = System.Net.WebRequest.Create("https://mytestserver.com/api/usr") as System.Net.HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/json;version=1";
request.Headers.Add("Content-Type", "application/json;version=1");
request.Headers.Add("Accepts", "application/json;version=1");
request.Headers.Add("Authorize", "key {key}");
using (var writer = new System.IO.StreamWriter(request.GetRequestStream())) {
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes("{\n \"firstName\": \"Dan\",\n \"lastName\": \"Eccles\",\n \"preferredNumber\": 1,\n \"email\" : \"testuser#example.com\",\n \"password\": \"you cant get the wood\"\n}");
request.ContentLength = byteArray.Length;
writer.Write(byteArray);
writer.Close();
}
string responseContent;
using (var response = request.GetResponse() as System.Net.HttpWebResponse) {
using (var reader = new System.IO.StreamReader(response.GetResponseStream())) {
responseContent = reader.ReadToEnd();
}
This is fairly straight forward to move across, except for the serialisation code. Is there a particular way this has to be done for RestSharp? I've tried creating an object and using
var json = JsonConvert.SerializeObject(user);
restRequest.RequestFormat = DataFormat.Json;
restRequest.AddBody(json);
but the server still comes back with an error.
I'm also currently using JSON.NET for deserialization to an error object when the user passes in bad data. Is there a way I can deserialize to error object based on a single string using RestSharp?
You're close, but you don't need to worry about serialization with RestSharp.
var request = new RestRequest(...);
request.RequestFormat = DataFormat.Json;
request.AddBody(user); // user is of type User (NOT string)
By telling it that the format is JSON, then passing your already-serialized-as-JSON string, RestSharp is actually encoding it again as a string.
So you pass the string: {"firstName":"foo"} and it actually gets sent to the server as a JSON string object: "{\"firstName\":\"foo\"}" (note how your JSON is escaped as a string literal), which is why it's failing.
Note you can also use an anonymous object for the request:
var request = new RestRequest(...);
request.RequestFormat = DataFormat.Json;
request.AddBody(new{
firstName = "Dan",
lastName = "Eccles",
preferredNumber = 1,
// etc..
});
You use the same typed objects with the response (eg, RestSharp deserializes for you):
var response = client.Execute<UserResponse>(request);
// if successful, response.Data is of type UserResponse

Categories