Hey all this is the first time I am trying out RESTsharp. I am trying to create a GET call that looks like this:
http://labs.bible.org/api/?passage=random&type=json
I've tried the following with looking at some online examples:
var client = new RestClient("http://labs.bible.org/");
var request = new RestRequest("api/?{0}&{1}", Method.GET);
request.AddParameter("passage", "random");
request.AddParameter("type", "json");
var queryResult = client.Execute<List<quotesAPI>>(request).Data;
When I put a stop on the queryResult it just says NULL.
quotesAPI looks like this:
public class qAPI
{
public string bookname { get; set; }
public string chapter { get; set; }
public string verse { get; set; }
public string text { get; set; }
}
So how do I need to format the call in order for it to work as it should be?
update 1
var client = new RestClient("http://labs.bible.org/");
var request = new RestRequest("api", Method.GET);
request.AddParameter("passage", "random");
request.AddParameter("type", "json");
client.AddHandler("application/x-javascript", new RestSharp.Deserializers.JsonDeserializer());
var queryResult = client.Execute<List<quotesAPI>>(request).Data;
First, there is no need to create rest client like this:
new RestRequest("api/?{0}&{1}", Method.GET);
This will result in query to http://labs.bible.org/api/?{0}&{1}&passage=random&type=json. In this specific case it might still "work", but in general you should of course avoid this. Instead, create it like this:
new RestRequest("api", Method.GET);
For GET methods, parameters you then create will be appended to query string for you.
Another problem here is unusual content type of response. Response for your query has content type application/x-javascript. RestSharp has no idea what to do with such content type, so you should tell it:
var client = new RestClient("http://labs.bible.org/");
client.AddHandler("application/x-javascript", new RestSharp.Deserializers.JsonDeserializer());
Here you say that it should deserialize response with such content type as json. After that you should receive expected result.
Related
Hey I am having a weird issue I can't figure out. Basically I am trying to make a simple httpClient post request but I keep getting an "Invalid json primitive:." I have checked on https://jsonlint.com/ and it says this is valid json but my application states otherwise. Any info would be greatly appreciated?
string test = "{\"CurrentUser\":null,\"Stacktrace\":\"System.UnhandledExceptionEventArgs\",\"OtherData\":null,\"UserInput\":\"\",\"TimeStamp\":\"2017-10-10T16:48:58.606512-04:00\"}"
HttpContent httpContent = new StringContent(test);
await httpClient.PostAsync("/api/logException", httpContent);
And the client is initialized like:
httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(this.serverURL);
httpClient.Timeout = TimeSpan.FromSeconds(400);
Instead of writing the JSON format on your own (which is prone to error), how about you simply create an object and serialize it to JSON. Have c# do the heavy lifting. First create a class like:
public class Model
{
public string CurrentUser { get; set; } = null;
public string Stacktrace { get; set; } = "System.UnhandledExceptionEventArgs";
public string UserInput { get; set; } = String.Empty;
public string OtherData { get; set; } = null;
public string TimeStamp { get; set; } = "2017-10-10T16:48:58.606512-04:00";
}
Then initialize an object of this class and simply use JavaScriptSerializer to serialize it into json:
Model md = new Model();
System.Web.Script.Serialization.JavaScriptSerializer ser = new System.Web.Script.Serialization.JavaScriptSerializer();
var json = ser.Serialize(md);
The result will be in json:
{"CurrentUser":null,"Stacktrace":"System.UnhandledExceptionEventArgs","UserInput":"","OtherData":null,"TimeStamp":"2017-10-10T16:48:58.606512-04:00"}
I'm no expert, but since nobody else has responded, perhaps you just need to set the content type to JSON?
HttpContent httpContent = new StringContent(test, Encoding.UTF8, "application/json");
See POSTing JsonObject With HttpClient From Web API
Try to String.Replace("\", string.Empty) to your json. Perhaps this will work.
Hey thanks for the answers. You are all correct and I appreciate the help. The issue was in the end not actually json. Basically this error was propagating and actually appearing twice after I thinking it was handled. So where I thought it was telling me invalid json existed (where it was breaking) was actually it repeating the same error message from further up the code.
Thanks again.
Good morning! I'm still learning my way around REST API calls and generally processing HTTP requests, so please provide any feedback :)
I'm trying to make a GET call to a web service, which should return a JSON string that's a set of information, which is supposed to be a SQL record returned in a sort of dictionary-like manner.
However, I am having several hiccups and don't know if I'm approach the resolution correctly:
Call web service. Define it as a 'GET' call.
Process the response and read it using a StreamReader.
Using the NewtonSoft JSON method, deserialize the response into a dictionary format. <-- Currently stuck here.
Use dictionary to my liking.
// Call the Web Service
string url = "{URL HERE}";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.ContentType = "application/json";
request.ContentLength = 0;
//Dictionary<string, string> dataList = null;
try
{
WebResponse response = request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
var json = reader.ReadToEnd();
//Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
var data = JsonConvert.DeserializeObject<List<KeyValuePair<string, List<KeyValuePair<string, string>>>>>(json);
var dataDictionary = data.ToDictionary(
x => x.Key,
x => x.Value.ToDictionary(y => y.Key, y => y.Value));
//dataList = (Dictionary<string, string>) dataDictionary;
var test = dataDictionary["Key"];
What the JSON string from the call sort of looks like:
"[{\"Number\":4,\"FieldABC\":\"ABC\"}]"
Other solutions I have tried:
Using the data type Dictionary instead.
Various other method calls, like the ones commented out in the code.
Another SO post suggested the ToDictionary() call.
Errors I have run into:
{"Value cannot be null.\r\nParameter name: source"} System.Exception {System.ArgumentNullException}
Cannot convert JSON string to JSON object.
Am I misunderstanding how to process the response from the HTTP request? Or am I confusing / misusing data types? Any help is greatly appreciated!
Update: With all the answers below, the solution ended up being a combination of all of the comments! First, I used json2csharp.com to create the object. Then, using the updated HTTP calls recommended below, I deserialized the JSON into a type Lists so that I got a list of length 1 that I could access my information from. Thanks everyone!
So when I use http://json2csharp.com/ for example to use your JSON, I would get:
public class ClassName
{
public int Number { get; set; }
public string FieldABC { get; set; }
}
Use HttpClient, that makes it easier:
using (var client = new HttpClient())
{
var response = await client.GetAsync(progressUrl);
var yourObject == JsonConvert.DeserializeObject<ClassName>(await response .Content.ReadAsStringAsync());
}
Continue with the rest...
You can also use HttpClientExtensions Class.
Cheers!
First make a POCO which exactly matches the response string. Something like this:
public class MyResponseObject {
public int Number { get; set; }
public string FieldABC { get; set; }
// other properties here
}
Assuming you are sent an array of these objects as [{\"Number\":4,\"FieldABC\":\"ABC\"}] suggests then you can deserialize it using
JsonConvert.DeserializeObject<List<MyResponseObject>>(json);
If it is a more complicated object then you can include additional nested objects in your principal object:
public class MyNestedObject {
public string NestedName { get; set; }
public bool IsEnabled { get; set; }
}
public class MyResponseObject {
public List<MyNestedObject> NestedObjects { get; set; }
}
Once you have a List<MyResponseObject> you may find you don't need a dictionary at all, or if you do you can take advantage of the many Linq Enumerable methods without worrying about JSON.
Use HttpClient instead of HttpWebRequest, as follows:
using (var httpClient = new System.Net.Http.HttpClient())
{
httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
var response = await httpClient.GetAsync(url);
var data = await response.Content.ReadAsStringAsync();
Dictionary<string, string> ValueList = JsonConvert.DeserializeObject<Dictionary<string, string>>(data);
}
I need to call this method in MVC controller and pass the UpdateRequest object as json format. how I can do that?
[HttpPost]
[Route("updatecertificate")]
public void updatecertificate([FromBody] UpdateRequest certificatereviewed)
{
loansRepository.updatecertificate(certificatereviewed.Id, certificatereviewed.CertificateReview);
}
and this is the input class:
public class UpdateRequest {
public int Id { get; set; }
public bool CertificateReview { get; set;}
}
this is how I call and send separate variable but now I like to send the class object in json format.
private async Task UpdateFundingCertificateReviewed(int id, bool fundingCertificateReviewed)
{
await httpClient.PostAsync(string.Format("{0}/{1}", LoanApiBaseUrlValue, updatecertificate),null);
}
I personally like Newtonsoft.Json to serialize the object.
private async Task UpdateFundingCertificateReviewed
(int id, bool fundingCertificateReviewed)
{
using (var client = new HttpClient())
{
var url = string.Format("{0}/{1}", LoanApiBaseUrlValue, updatecertificate);
var updateRequest = new UpdateRequest { Id = 1, CertificateReview = true};
var data = JsonConvert.SerializeObject(updateRequest);
await client.PostAsync(url, data);
}
}
FYI: Async without return is not a good practice. However, it is out of the original question.
If you want to transform an object into a JSON string, see this question: Turn C# object into a JSON string in .NET 4
var json = new JavaScriptSerializer().Serialize(obj);
Is this what you are after or do you want to know how to construct the http request with a JSON object in the body?
your questionis not very clear, what is the outcome that you expect ?
If you want to POST an request with JSON body you can check the #Win comment,
however if you want to make an Response from the Api to the MVC project you should do a bit more steps tough. :))
My controller method is as follows
public ActionResult Index()
{
Tweets model = null;
var client = new HttpClient();
var task = client.GetAsync("http://localhost:33615/api/product").ContinueWith((t) =>
{
var response = t.Result;
var readtask = response.Content.ReadAsAsync<Tweets>();
readtask.Wait();
model = readtask.Result;
});
task.Wait();
return View(model.Result);
}
The url return the row as follws:
[{"Id":1,"Name":"Honda Civic","Description":"Luxury Model 2013"},{"Id":2,"Name":"Honda Accord","Description":"Deluxe Model 2012"},{"Id":3,"Name":"BMW V6","Description":"V6 Engine Luxury 2013"},{"Id":4,"Name":"Audi A8","Description":"V8 Engine 2013"},{"Id":5,"Name":"Mercedes M3","Description":"Basic Model 2013"}]
My Tweets and tweet class are as follows:
public class Tweets
{
public Tweet[] Result;
}
public class Tweet
{
[JsonProperty("Name")]
public string Name { get; set; }
[JsonProperty("Description")]
public string Description { get; set; }
}
I can't figure it out where i do mistake.it gives me following error:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'RestFiddlerTest.Controllers.Tweets' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly
How to fix this.
I've double checked your code and there are a few issues with it.
First of all, I don't see your logic to deserialize to Json, according to the JSon object, I'm guessing that you're using Newtonsoft.Json?
Then you have a class Tweets which contains an array of Tweet objects.
Now, when you create a small sample, like the following:
var dataToSerialize = new Tweets();
dataToSerialize.Result = new [] { new Tweet { Description = "Desc", Name = "Name" } };
var data = JsonConvert.SerializeObject(dataToSerialize);
The output of this piece of code will be the following:
{"Result":[{"Id":null,"Name":"Name","Description":"Desc"}]}
This is not the same as the output you get from your WebAPI.
Now, when you do use Newtonsoft.Json, when serializing your object, you are probably doing something like this:
const string JSon = "[{\"Id\":1,\"Name\":\"Honda Civic\",\"Description\":\"Luxury Model 2013\"},{\"Id\":2,\"Name\":\"Honda Accord\",\"Description\":\"Deluxe Model 2012\"},{\"Id\":3,\"Name\":\"BMW V6\",\"Description\":\"V6 Engine Luxury 2013\"},{\"Id\":4,\"Name\":\"Audi A8\",\"Description\":\"V8 Engine 2013\"},{\"Id\":5,\"Name\":\"Mercedes M3\",\"Description\":\"Basic Model 2013\"}]";
var data = JsonConvert.DeserializeObject<Tweets>(JSon);
Note: I've put the Json string in a string because I didn't have the time to write a full WebAPI.
Now, this will not work, because the string I input and that's also the one that your controller does return is not a Tweets object (remember you're missing the Result in your JSon string? Instead, this is a array of Tweet objects, so you can change your code like the following:
var data = JsonConvert.DeserializeObject<Tweet>(JSon);
Unfortunately, you will receive the exact same error. So why is that? Because you're trying to deserialize your object into an object of type Tweet while your object is an array of type Tweet.
So, modify your code like the following:
var data = JsonConvert.DeserializeObject<Tweet[]>(JSon);
Now, you're deserializing your object into the correct type.
So, I do hope that this post will help you.
Kind regards,
I used Newtonsoft.Json.
public ActionResult Index()
{
List<Tweet> model = null;
var client = new HttpClient();
var task = client.GetAsync("http://localhost:33615/api/product").ContinueWith((t) =>
{
var response = t.Result;
var readtask = response.Content.ReadAsAsync<List<Tweet>>();
readtask.Wait();
model = readtask.Result;
});
task.Wait();
return View(model);
}
How do I correctly deserialise the results of this call (you can click to see output):
https://bitpay.com/api/rates
I'm using a POCO object like this:
public class BitpayPrice
{
public string code { get; set; }
public string name { get; set; }
public double rate { get; set; }
}
And I'm calling the API like so:
var client = new RestClient();
client.BaseUrl = "https://bitpay.com";
var request = new RestRequest("/api/rates", Method.GET);
var response = client.Execute<BitpayPrice[]>(request);
Now, I know that the call to execute is wrong, but how do I un-wrongify it? I'd like to get back an array of BitcoinPrice objects.
RestSharp doesn't support deserializing into array, the best you can get is a List<>:
var response = client.Execute<List<BitpayPrice>>(request);
The reason is that types that you can deserialize to are required to have public parameterless constructor (for performance reasons mostly).