I have created small class
class JsonResponse
{
public string Response { get; set; }
}
Then in my program I send some json data and wait store reply to the following variable
var ResultJSON = Post(uri, values);
while parsing I get
Service Error: Cannot convert object of type 'System.String' to type
'App.someclass+JsonResponse'
using Newtonsoft.Json;
class JsonResponse
{
public string Response { get; set; }
}
class Utility
{
public JsonResponse JsonDeserialisation(string response)
{
TextReader textReader = new StreamReader(response);
JsonTextReader jsonReader = new JsonTextReader(textReader);
return JsonSerializer.CreateDefault().Deserialize<JsonResponse>(jsonReader);
}
}
class Main
{
static void Program()
{
var ResultJSON = "Json String received from post";//Post(uri, values);
var deserialisedJson = Utility.JsonDeserialisation(ResultJSON);
}
}
Add newtonSoft.json nuget package to project
try
var Result = new JavaScriptSerializer().Deserialize<JsonResponse>(ResultJSON.**Response**);
looks to me that you are trying to deserialize from an object rather than the string response
Try this, may give your JSON file to result variable.
var result = Convert.ToString(ResultJSON);
Try using using newtonsoft.json downloadable here or use the nuget package.
It has a function that does exactly what you want. Expecting the result of the Post is in string format of course.
var result = JsonConvert.DeserializeObject<JsonResponse>(ResultJSON);
Your JsonResponse class must look exacly the same as the json your getting. So make sure if you get more data in the json that you want to save in the class the names are the same.
If you have anymore questions feel free to ask.
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);
}
On my server I tried this test code:
[AllowAnonymous]
[Route("GetX")]
public IQueryable<Phrase> GetX()
{
var phrases = new List<PhraseX>
{
new PhraseX() {Keyword="abc", Translation1="abc1", Translation2="abc2" },
new PhraseX() {Keyword="def", Translation1="def1", Translation2="def2" },
new PhraseX() {Keyword="ghi", Translation1="ghi1", Translation2="ghi2" },
};
return db.Phrases;
}
Here's what I have so far on the client which is a terminal application:
var request = HttpWebRequest.Create("http://www.example.com/api/Phrase/GetX");
request.ContentType = "application/json";
request.Method = "GET";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
I am getting the expected data back but now I am not sure how can I get the data that's returned as json back into a list? Any suggestions on how I could do this?
You need to deserialize the JSON to C# objects.
These links will help you:
https://msdn.microsoft.com/en-us/library/bb412179(v=vs.110).aspx
http://www.newtonsoft.com/json/help/html/deserializeobject.htm
This is how you may do it:
string jsonStr = "[{Keyword:\"abc\", Translation1:\"abc1\", Translation2:\"abc2\" },{Keyword:\"def\", Translation1:\"def1\", Translation2:\"def2\" },{Keyword:\"ghi\", Translation1:\"ghi1\", Translation2:\"ghi2\" }]";
JavaScriptSerializer jss = new JavaScriptSerializer();
List<PhraseX> phrases = jss.Deserialize<List<PhraseX>>(jsonStr);
where PhraseX is a class-
public class PhraseX
{
public string Keyword { get; set; }
public string Translation1 { get; set; }
public string Translation2 { get; set; }
}
Note: You will find JavaScriptSerializer class in System.Web.Extensions.dll
You may also use JSON.NET for same.
Hope it helps.
You can deserialize the JSON to C# objects, as stated in the previous answer.
Using Json.NET (Newtonsoft.Json namespace), you can pass your JSON data to the JsonConvert.DeserializeObject<T>(json_data) method, with T being the data type the JSON should be deserialized into and json_data obviously being the JSON data you have received. You can obviously also use the built-in JavaScriptSerializer if you don't want to introduce a third-party dependency to your solution.
Visual Studio gives you a very easy way to create the C# classes for your JSON, have a look at my answers here and here.
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);
}
I get the following JSON that I am trying to convert to a business object using RestSharp
{
"valid":true,
"data":[
{
"dealerId":"4373",
"branchId":"4373",
}
]
}
I wish to convert to:
public class Dealer
{
public string dealerId ;
public string branchId;
}
But this fails, though the JSON is fine:
var client = new RestClient("http://www.????.com.au");
var request = new RestRequest(string.Format("service/autocomplete/dealer/{0}/{1}.json", suburb.PostCode, suburb.City.Trim().Replace(" ", "%20")), Method.GET);
var response2 = client.Execute<Dealer>(request);
return response2.Data;
Your business object doesn't match the response JSON you are getting back. If you want your response to serialize, your C# object would look something like
public class DealerResponse
{
public bool valid { get;set; }
List<Dealer> data { get;set; }
}
public class Dealer
{
public string dealerId;
public string branchId;
}
I haven't tested this code, but even though you are only interested in the information in 'data', your response C# objects still need to represent the whole JSON response to serialize correctly.
Hope that helps.