I have this JSON response:
{
"post_parameters_error_flag": false,
"data_error_flag": false,
"row_count": 7,
"message": "Operazione completata.",
"title": [
"title0",
"title1",
"title2",
"title3",
"title4",
"title5",
"title6"
],
"data": [
"value0",
"value1",
"value2",
"value3",
"value4",
"value5",
"value6",
"value7"
]
}
I need to write in a list (for example) all values obtained from 'data' array but I don't know how to get data from response:
string URL = "myurl";
string Params = string.Format("hwid={0}&building={1}", Utils.UUID(), "test");
Request HTTPRequest = new Request();
JObject JSONObject = JObject.Parse(await HTTPRequest.PostAsyncResponse(URL, Params));
//now? what can i do
Any idea to solve?
You can either use like this:
var result = await HTTPRequest.PostAsyncResponse(URL, Params)
var token = JToken.Parse(result);
var data= token.Value<JArray>("data");
Or you can also use JsonPath:
var result = await HTTPRequest.PostAsyncResponse(URL, Params)
var token = JToken.Parse(result);
var data = token.SelectTokens("$.data[*]");
But really, you should be serilizing into an object and then using the properties to get the data (or other properties):
public class RootObject
{
public bool post_parameters_error_flag { get; set; }
public bool data_error_flag { get; set; }
public int row_count { get; set; }
public string message { get; set; }
public List<string> title { get; set; }
public List<string> data { get; set; }
}
var result = await HTTPRequest.PostAsyncResponse(URL, Params)
var item = JsonConvert.DeserializeObject<RootObject>(result);
var data = item.data;
Try this,
var data = JObject.Parse(await HTTPRequest.PostAsyncResponse(URL, Params))["data"]
OR
var jsonObject = (JObject)JsonConvert.DeserializeObject(await HTTPRequest.PostAsyncResponse(URL, Params));
var data = (JObject)(jsonObject.Property("data").Value);
Related
I have some array data coming from an API in JSON format, and I want to convert an array type to a list. There is an ASP.NET MVC project and I used the list in Index page. How can I deserialize the array format into a list?
Controller
public async Task<IActionResult> ListCountries()
{
List<Country> countries = new List<Country>();
HttpClient _client = new HttpClient();
HttpResponseMessage _response = new HttpResponseMessage();
_client = _apiHelper.Initial();
_response = await _client.GetAsync("api/Countries/getall");
if (_response.IsSuccessStatusCode)
{
var results = _response.Content.ReadAsStringAsync().Result;
countries = JsonConvert.DeserializeObject<List<Country>>(results);
}
return View(countries);
}
Data
"data": [
{
"id": 1,
"countryName": "Afghanistan"
},
{
"id": 2,
"countryName": "Albania"
},
{
"id": 3,
"countryName": "Algeria"
},
Entity
public class Country
{
[Key]
public int Id { get; set; }
public string CountryName { get; set; }
}
Your json data is invalid format. Json maybe have to be like this:
{
"data": [
{
"id": 1,
"countryName": "Afghanistan"
},
{
"id": 2,
"countryName": "Albania"
},
{
"id": 3,
"countryName": "Algeria"
}
]
}
After that you should create 2 c# class like this:
public class JsonData
{
public List<Country> data { get; set; }
}
public class Country
{
public int id { get; set; }
public string countryName { get; set; }
}
Then you can deserialize it without any error.
public async Task<IActionResult> ListCountries()
{
List<Country> countries = new List<Country>();
HttpClient _client = new HttpClient();
HttpResponseMessage _response = new HttpResponseMessage();
_client = _apiHelper.Initial();
_response = await _client.GetAsync("api/Countries/getall");
if (_response.IsSuccessStatusCode)
{
var results = _response.Content.ReadAsStringAsync().Result;
countries = JsonConvert.DeserializeObject<JsonData>(results);
}
return View(countries);
}
The object has a variable data that contains the countries whereas the class you're trying to serialize to does not.
Having a class such as:
public class Country{
[JsonProperty('data')]
public List<data> Details {get;set;}
public Country(){
Details = new List<data>();
}
public class data{
[Key]
[JsonProperty('id')]
public int Id { get; set; }
[JsonProperty('countryName')]
public string CountryName { get; set; }
}
and then to deserialize it you would need:
countries = JsonConvert.DeserializeObject<Country>(results);
When it deserializes the object it will map data to the Details variable in the class Country and map each value in the response array to the data class
The structure shown is not a list/array of Countries but an object which has a property data which is a list/array of Contries:
public class Result
{
public List<Country> Data {get; set;}
}
...
var r = JsonConvert.DeserializeObject<Result>(results);
var countries = r.Data;
Minor note. Since you're using Json.NET it's OK that your properties don't match the case in json, but if you switch to System.Text.Json this would become an issue.
you have to parse and use JArray inside of your result
var countries = JObject.Parse(results)["data"].ToObject<List<Country>>();
// data for test
var results = #"{""data"": [
{
""id"": 1,
""countryName"": ""Afghanistan""
},
{
""id"": 2,
""countryName"": ""Albania""
},
{
""id"": 3,
""countryName"": ""Algeria""
}]}";
I'm getting an error in PostMan fetching data from my API:
System.ArgumentNullException: Value cannot be null. (Parameter 'factory')
This is my controller:
[HttpGet("basket/{identifier}")]
public async Task<IEnumerable<NewBasketDTO.ItemDTO>> FetchBasketEntries(string identifier)
{
var httpRequestMessage = new HttpRequestMessage(
HttpMethod.Get,
$"https://localhost:5500/api/Basket/{identifier}")
{
Headers = { { HeaderNames.Accept, "application/json" }, }
};
var httpClient = httpClientFactory.CreateClient();
using var httpResponseMessage =
await httpClient.SendAsync(httpRequestMessage);
var basketEntires = Enumerable.Empty<NewBasketDTO.ItemDTO>();
if (!httpResponseMessage.IsSuccessStatusCode)
return basketEntires;
using var contentStream =
await httpResponseMessage.Content.ReadAsStreamAsync();
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
var basketDTO = await JsonSerializer.DeserializeAsync
<DTO.NewBasketDTO.ItemDTO>(contentStream, options);
basketDTO = new NewBasketDTO.ItemDTO
{
ProductId = basketDTO.ProductId,
Quantity = basketDTO.Quantity
};
return basketEntires; // 200 OK
}
Here is my model DTO:
public class NewBasketDTO
{
public class ItemDTO
{
public int ProductId { get; set; }
public int Quantity { get; set; }
}
[ActivatorUtilitiesConstructor]
public class BasketDTO
{
public string Identifier { get; set; }
public List<ItemDTO> Items { get; set; }
}
}
I'm trying to get this data here from my API:
[
{
"productId": 0,
"quantity": 0
}
]
What am I doing wrong? I'm trying to fetch data from my API with Http in my controller and I want that data to be added to my NewBasketDTO and returned in JSON format so that I can post it to another database later on but I can't even seem to get it correctly without it giving me this error of value cannot be null
I'm working on GitHub API and I want to manipulate the JSON response of this API so I have this API code
public class TrendRepo
{
public IEnumerable<object> Data;
}
[HttpGet]
public async Task<JsonResult> GetTrendingRepos()
{
var date = DateTime.Now.AddDays(-30).ToString("yyyy-MM-ddThh:mm:ssZ");
string trendingReposLanguagesUrl = #"https://api.github.com/search/repositories?q=created:>" + (date) + "&sort=stars&order=desc&per_page=10";
HttpWebRequest request = WebRequest.CreateHttp(trendingReposLanguagesUrl);
request.Accept = "application/json";
request.UserAgent = "request";
WebResponse response = await request.GetResponseAsync();
Stream data = response.GetResponseStream();
StreamReader reader = new StreamReader(data ?? throw new InvalidOperationException());
var readerResult = await reader.ReadToEndAsync();
//var jObj2 = JsonConvert.DeserializeObject<dynamic>(readerResult);
JToken token = JObject.Parse(readerResult);
var items = token["items"];
var arr = new List<object>();
List<dynamic> tripDetailsCollection = new List<dynamic>();
if (items != null)
{
foreach (dynamic o in items)
{
arr.Add(o.language);
arr.Add(o.id);
arr.Add(o.full_name);
arr.Add(o.html_url);
arr.Add(" ");
tripDetailsCollection.AddRange(arr);
}
}
TrendRepo trendRepo = new TrendRepo()
{
Data = arr,
};
return new JsonResult(trendRepo);
}
which return the response like this
{
"data": [
"Python",
319029846,
"beurtschipper/Depix",
"https://github.com/beurtschipper/Depix",
" ",
"C++",
311683390,
"WerWolv/ImHex",
"https://github.com/WerWolv/ImHex",
" ",
null,
316705066,
"peng-zhihui/PocketLCD",
"https://github.com/peng-zhihui/PocketLCD",
" "
]
}
but what I want is to be something like this
{
"data": [
"Python",
319029846,
"full_name":[
"beurtschipper/Depix",
"beurtschipper/Depix",
],
"https://github.com/beurtschipper/Depix",
" ",
]
"data": [
"C++",
311683390,
"full_name":[
"beurtschipper/Depix",
"WerWolv/ImHex",,
],
"https://github.com/WerWolv/ImHex",
" ",
]
"data": [
null,
316705066,
"full_name":[
"beurtschipper/Depix",
"WerWolv/ImHex",,
],
"https://github.com/peng-zhihui/PocketLCD",
" "
]
}
I tried to add another foreach within the existing one to kind of loop the
property but it gave me the same result.
also, I need to select a distinct language which is easy to do but
the trick move is I want all repos names and count which depend on this
language within the array, like in the JSON response I want above.
Any help I would be grateful.
#Hazeem, Spent bit time to see what we can do get the search results closer to your expectations, basically the way you defined JSON is useless no one would be able to parse, I don't think even serializer would accept for example data collection is not separated by commas, I tied up code a bit to work closer to what you want.
Code:
var tripDetailsCollection = new List<object>();
var date = DateTime.Now.AddDays(-30).ToString("yyyy-MM-ddThh:mm:ssZ");
string trendingReposLanguagesUrl = #"https://api.github.com/search/repositories?q=created:>" + (date) + "&sort=stars&order=desc&per_page=10";
var request = WebRequest.CreateHttp(trendingReposLanguagesUrl);
request.Accept = "application/json";
request.UserAgent = "request";
var response = await request.GetResponseAsync();
Stream data = response.GetResponseStream();
JToken token;
using (var reader = new StreamReader(data ?? throw new InvalidOperationException()))
{
var readerResult = await reader.ReadToEndAsync();
token = JObject.Parse(readerResult);
}
if (token != null)
{
var items = token["items"];
if (items != null)
{
foreach (dynamic o in items)
{
var arr = new
{
data = new List<object>
{
o.language,
o.id,
o.full_name,
o.html_url,
" "
}
};
tripDetailsCollection.Add(arr);
}
}
}
var json = JsonConvert.SerializeObject(tripDetailsCollection);
Result - you should be able loop through the collection and use it elsewhere.
What I need is to wrap my TrendRepo class with the Parent class with the same property values and DeserializeObject of the instead of here's the answer and feel free if anything not obvious.
public class Root
{
[JsonPropertyName("items")]
public List<Items> Items { get; set; }
}
public class Items //TrendRepo
{
[JsonPropertyName("language")]
public string Language { get; set; }
[JsonPropertyName("id")]
public int Id { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("full_name")]
public string Full_Name { get; set; }
public string total_count { get; set; }
}
and edit the API like this
var readerResult = await reader.ReadToEndAsync();
Root jObj2 = JsonConvert.DeserializeObject<Root>(readerResult);
var result = jObj2.Items.Select(x => new
{
x.Language,
x.Id,
x.Full_Name,
x.Name
}).GroupBy(x => x.Language).ToArray();
return new JsonResult(result);
I am new to this and apologize if it is a duplicate question. I have tried so many different things at this point I'm not sure the right way to do this.
I am trying to write a function to loop through a JSON and get the value of model for certain conditions (ie: qty != null, and sector = 1, position = 1.
I also need to count the number of occurrences for each unique model.
Any help would be greatly appreciated.
Here is what the JSON looks like.
[ { "sector": "1", "position": "1", "qty": "1", "model": "SBNHH-1D65C" },
{ "sector": "2", "position": "1", "qty": "1", "model": "" },
{ "sector": "3", "position": "1", "qty": "1", "model": "DC6-48-60-18-8F" },
{ "sector": "1", "position": "2", "qty": "1", "model": "SBNHH-1D65C" },
{ "sector": "2", "position": "2", "qty": "1", "model": "DC6-48-60-18-8F" } ]
public class AntennaItems
{
public AntennaItems[] root { get; set; }
public int sector { get; set; }
public int position { get; set; }
public string qty { get; set; }
public string model { get; set; }
}
string requestBodyString = await new StreamReader(req.Body).ReadToEndAsync();
var newJsonString = #"{root:" + requestBodyString + #"}";
List<string> modelList = new List<string>();
var jsonObj = JsonConvert.DeserializeObject<AntennaItems>(newJsonString);
foreach (var elem in jsonObj.root)
{
modelList.Add(elem.model);
}
return new OkObjectResult($"modelList = {modelList}");
Currently I'm getting this response:
modelList = System.Collections.Generic.List`1[System.String]
You'd return your modelList in interpolation with string name modelList and interpolation return you the type of your modelList and in your case its a System.Collections.Generic.List'1[System.String].
So this line
return new OkObjectResult($"modelList = {modelList}");
Give you
modelList = System.Collections.Generic.List`1[System.String]
So instead of returning like above try to return your modelList with anonymous type so you will be able to get actual data containing modelList like
return new OkObjectResult(new { modelList = modelList});
Or Simply
return new OkObjectResult(modelList);
I think you don't need root property. I have modified the class little bit and removed the root property from it:
public class AntennaItems
{
public int sector { get; set; }
public int position { get; set; }
public string qty { get; set; }
public string model { get; set; }
}
public HttpResponse ParseJson()
{
string requestBodyString = await new StreamReader(req.Body).ReadToEndAsync();
var newJsonString = #"{root:" + requestBodyString + #"}";
List<string> modelList = new List<string>();
var jsonObj = JsonConvert.DeserializeObject<List<AntennaItems>>(newJsonString);
foreach (var elem in jsonObj)
{
modelList.Add(elem.model);
}
return new OkObjectResult($"modelList = {modelList}");
}
You need to deserialize it in List. Let me know if it helps.
public class AntennaItems
{
public int sector { get; set; }
public int position { get; set; }
public string qty { get; set; }
public string model { get; set; }
[FunctionName("AntennaSort")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
List<string> modelList = new List<string>();
var jsonObj = JsonConvert.DeserializeObject<List<AntennaItems>>(requestBody);
foreach (var elem in jsonObj)
{
modelList.Add(elem.model);
}
return new OkObjectResult($"modelList = {modelList}");
}
The result is
modelList = System.Collections.Generic.List`1[System.String]
how do I get only the "intent" field from the JSON format code from LUIS return result in C#?
I have already done deserialization like this:
public class ResponseContent
{
[BsonId]
public string query { get; set; }
public string topScoringIntent { get; set; }
public string intent { get; set; }
public string entities { get; set; }
}
public class topScoringIntent
{
public string intent { get; set; }
public string score { get; set; }
}
And this is the LUIS return result:
"query": "Hello.",
"topScoringIntent":
{
"intent": "Greeting",
"score": 0.9447609
},
"intents":
[
{
"intent": "Greeting",
"score": 0.9447609
},
{
"intent": "Request",
"score": 0.09726282
},
{
"intent": "None",
"score": 5.523394E-10
}
],
"entities": []
And I only want the "intent" field from the "TopScoringIntent". How can I get that using C#? Below is the code that I tried but nothing came out:
var uri = "https://southeastasia.api.cognitive.microsoft.com/luis/v2.0/apps/" + luisAppId + "?" + queryString;
var response = await client.GetAsync(uri);
var responseContent = await response.Content.ReadAsStringAsync();
var responseitem = JsonConvert.SerializeObject(responseContent,Formatting.Indented);
JToken content = JToken.Parse(responseitem);
var intentOnly = (from s in content.Children()["ResponseContent"]select s).ToList();
foreach (var item in intentOnly.Children().ToList())
{
Console.WriteLine(item.ToObject<ResponseContent>().TopScoringIntent);
}
This is not a bot so I am not using any bot framework to do this.
Thank you.
Get it done by using the following code:
var jsonresponse = JObject.Parse(responseContent);
intentonly = jsonresponse.SelectToken("intents[0].intent").ToString();