Sample Json:
{
"success": true,
"status": 200,
"data": [
{
"ProfileID": "1001",
"Name": "Jane Doe",
"HomePhone": "555-1212",
"Address1": "123 Elm St"
},
{
"ProfileID": "1002",
"Name": "Rick Fox",
"HomePhone": "555-1213",
"Address1": "123 Ok St"
}
]
}
My code so far:
using Newtonsoft.Json;
private void popGrid()
{
var client = new HttpClient();
client.BaseAddress = new Uri("http://the-api/");
var responseTask = client.GetAsync("member-list");
responseTask.Wait();
var result = responseTask.Result;
if (result.IsSuccessStatusCode)
{
var read_response = responseTask.Result.Content.ReadAsStringAsync();
read_response.Wait();
var read_result = read_response.Result;
dynamic response = JsonConvert.DeserializeObject(read_result);
var success = response.success;
var status = response.status;
var data = response.data;
// List<Root> myDeserializedClass = JsonConvert.DeserializeObject<List<Root>>(data);
if ((bool)success)
{
GridView1.DataSource = data;
GridView1.DataBind();
}
}
}
public class Root
{
public string ProfileID { get; set; }
public string Name { get; set; }
public string HomePhone { get; set; }
public string Address1 { get; set; }
}
The Errors: If I run the code as written, it runs through all the way without issue. However when the page renders I get an ugly error:
Type 'Newtonsoft.Json.Linq.JValue' in Assembly 'Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' is not marked as serializable.
Buried in the Stack Trace is one line that gives a clue(to me):
[ArgumentException: Error serializing value '1001' of type 'Newtonsoft.Json.Linq.JValue.']
So then I the added the (commented) line that uses the Root class. However, if I un-comment that line and run the code, I get the following error:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'The best overloaded method match for 'Newtonsoft.Json.JsonConvert.DeserializeObject<System.Collections.Generic.List<Root>>(string)' has some invalid arguments'
The above error seems to indicate that JsonConvert.DeserializeObject won't accept the var 'data' as an input. Any thoughts would be greatly appreciated.
CodePudding user response:
You can simplify the approach. Instead of trying to deserialize only part of the JSON, deserialize the whole thing into an object. Define an object structure which matches it:
public class Root
{
public bool success { get; set; }
public int status { get; set; }
public IEnumerable<Profile> data { get; set; }
}
public class Profile
{
public string ProfileID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string HomePhone { get; set; }
}
Then deserialize the response into that:
var result = JsonConvert.DeserializeObject<Root>(read_result);
Then you can access the collection in that object:
GridView1.DataSource = result.data;
CodePudding user response:
it is better to create async method , but if you can not , you have to fix your code
var response = client.GetAsync(api).Result;
if (response.IsSuccessStatusCode)
{
var json = response.Content.ReadAsStringAsync().Result;
var jsonParsed=JObject.Parse(json);
var success = jsonParsed["success"];
var status = jsonParsed["status"];
List<Root> data = jsonParsed["data"].ToObject<List<Root>>();
//or
DataTable data = jsonParsed["data"].ToObject<DataTable>();
if ((bool)success)
{
GridView1.DataSource = data;
GridView1.DataBind();
}
}