C# Rest Response in JSON Deserialize to Custom Object - c#

I have reviewed a lot of posts about this question and I am still having trouble. I am using Newtonsoft.Json and the following code:
string url = #"https://https://someSite.com/indexes('myIndex')search=SEARCH_PHONES:";
string phoneNumber = "5550005555";
url += phoneNumber;
HttpWebRequest request = HttpWebRequest.CreateHttp(url);
request.Method = "GET";
request.Headers.Add("api-key", "####");
WebResponse response = request.GetResponse();
Stream imageStream = response.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader readStream = new StreamReader(imageStream, encode);
string s = readStream.ReadToEnd();
JObject joResponse = JObject.Parse(s);
JArray array = (JArray)joResponse["value"];
string customer = array[0].ToString();
The problem is that array is returning as one long string. How do I access the individual key/value pairs? Below is the response I recieve:
{
"#odata.context": "https://someSite.com/indexes('myIndex')/$metadata#docs",
"value": [
{
"#search.score": 10.933167,
"CUSTOMER_DIM_ID": "77049309",
"SOURCE_CUSTOMER_ID": null,
"PORTSTORE_ID": "0326_1448401",
"FIRST_NM": "First Name",
"LAST_NM": "Last Name",
"ADDR_LINE_1": "133 Main St",
"ADDR_LINE_2": null,
"CITY": "MyCity",
"STATE_CD": "IL",
"POSTAL_CD": "99999",
"COUNTRY": "United States",
"EMAIL_ADDR": "myEmail#gmail.com",
"BIRTH_DT": null,
"PHONE": "5550005555",
"GENDER_CD": "F",
"SEARCH_EMAILS": [
"myEmail#gmail.com"
],
"SEARCH_PHONES": [
"5550005555"
],
"JUS_EMAIL_OPTIN": true,
"JCA_EMAIL_OPTIN": true,
"LCA_EMAIL_OPTIN": true,
"JUS_DM_OPTIN": true,
"JCA_DM_OPTIN": true,
"LCA_DM_OPTIN": true,
"MOBILE_OPTIN": false,
"LIFETIME_REVENUE": "138.1800",
"LIFETIME_UNITS": 7,
"NTH_ORDER": 2,
"FIRST_PURCHASE_DT": "2016-02-11T00:00:00Z",
"LAST_PURCHASE_DT": "2016-02-19T00:00:00Z",
"AVG_LAG": 8,
"IsDeleted": false,
"UPDATE_DT": "2016-02-19T00:00:00Z"
}
]
}
I don't have access to change the response. I tried to use json2sharp to create the objects and then simply deserialize but it said that the "#search.score" was invalid as well as "#odata.context". After I commented out those lines in my C# code it does not deserialize correctly (everything is null) I need to be able to retrieve the customer information and assign it to my custom class.

It looks like you're doing a little extra work here. Instead of
Stream imageStream = response.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader readStream = new StreamReader(imageStream, encode);
string s = readStream.ReadToEnd();
Do string s = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
Then, you can do a JsonConvert.DeserializeObject<MyType>(s) and that should get you your object.
Also in your object, make sure to use the appropriate serialization attributes wherever your names don't match up, if you wanted a particular naming style for example.

Don't manually parse through JSON unless you have a really good reason to do so.
Make a web request using your rest client of choice (postman/dhcp/etc.) and copy the response. Then create a new .cs file and go to Edit -> Past Special -> Paste Json as class.
From here you should get a mostly working POCO that can be used for deserializing the JSON using Newtonsoft.Json.JsonConvert.Deserialize<Class>(responseJson).
Note that newtonsoft defaults to camel case for json properties. Since your properties are not camel case, you need to explicitly define the property name.
[JsonProperty("ID")]
public int ID { get; set; }

Related

Cannot serialize stream data asp .net core

Trying to deserialize objects from HTTP response.
Response stream returns information in json and I already checked if it is valid in online deserializer.
I got the object class from the API framework so I think all of the properties should be configured for the response.
Code:
var request = new HttpRequestMessage(HttpMethod.Get,
"api_url");
var client = _clientFactory.CreateClient();
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
using var responseStream = await response.Content.ReadAsStreamAsync();
var reponseString = await response.Content.ReadAsStringAsync();
var data = await JsonSerializer.DeserializeAsync<IEnumerable<Tournament>>(responseStream);
}
else
{
GetBranchesError = true;
}
I see that information in responseString is correct but data objects are always null.
Weird part is that it partially works because it shows how many objects are in the responseStream but all of the object properties are nulls.
Also tried to set the stream position to 0 - didn't help.
Any idea what I am doing wrong to deserialize these objects?
Desirializer used - System.Text.Json;
Project asp .net core 3.1
The problem is that the properties you are looking for in the JSON array are actually wrapped inside an object called "tournament". It's easier to notice when you format the JSON string nicely like this for example:
[
{
"tournament": {
"id": 1,
"name": "name1",
...
}
},
{
"tournament": {
"id": 2,
"name": "name2",
...
}
}
]
To deserialize this I would suggest you make a wrapper class to handle that:
public class TournamentItem
{
[JsonPropertyName("tournament")]
public Tournament Tournament { get; set; }
}
And then deserialize to that class:
var data = await JsonSerializer.DeserializeAsync<IEnumerable<TournamentItem>>(responseStream);
Now data.Tournament will contain all the properties.
There might still be a few issues in your properties like Spam for example. The JSON string has a null as value, but the property is not nullable - I didn't check all your properties. DeserializeAsync will throw an error and tell you.

How to parse JSON in C# and find only certain parts

I have a file I got from a site that lists all textures and all names. I want to parse the JSON file and get just the name and texture parts get the url property and download the link with the name above.
I'm not sure how to get this because the whole file is large but I just want to get the url and the width and height. If they are 2048 or 4042. If they match get the name and download the URL and give the name value to the name of download.
So in summary
"name": "Metal_2_roughness.jpg",
"images": [
{
"height": 2048,
"createdAt": "2017-08-11T16:14:06.933292",
"updatedAt": "2017-08-11T16:14:06.933307",
"uid": "ae19ea6db7074248ac4e04b4db971913",
"width": 2048,
"options": {},
"url": "https://media.sketchfab.com/urls/cbfbf4d275c24eafa51eaf3a6c3c91b9/dist/textures/16fb95f74f4846079a32f15c2be35565/ae19ea6db7074248ac4e04b4db971913.jpeg",
"size": 1042057
},
If the height and width matches 2048 then check the name. Copy that then copy url and download the URL and give it the name property. But I'm not sure how to go about doing this as I never touched on JSON before.
https://paste.md-5.net/vecaxacafe.bash
Use WebRequest to request url for json and use Json.net to parse the response.
WebRequest webRequest = WebRequest.Create("your url");
HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();
Console.WriteLine(response.StatusDescription);
if (response.StatusDescription == "OK")
{
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
// Display the content.
dynamic stuff = JObject.Parse(responseFromServer);
Console.Write(stuff.results);
//Iterate over images using a loop
//Condition to check if height and width are same Eg: responseFromServer.images.height == responseFromServer.images.width
// Store the url in a variable like String url = responseFromServer.images.url
}
Hope this helps
Use json2csharp to convert the contents of your file to classes.
Then read the contents with File.ReadAllText() and deserialize the content with Json.NET like this var json = JsonConvert.DeserializeObject<RootObject>(content);
Then you can access the image height via json.images[0].height
If you are getting only a couple of fields from the entire JSON file, then the easiest way is to simply use JSON.NET and use the JObject method.
First install the Newtonsoft.Json Nuget Package.
Then, you can do something as simple as :
var myJsonString = File.ReadAllText("myfile.json");
var myJObject = JObject.Parse(myJsonString);
myJObject.SelectTokens("results[*].images[*].url").Values<string>();
Which will get you all URLs as strings. You may instead prefer to deserialize the entire JSON to an object using the JsonConvert method.
More Info : https://dotnetcoretutorials.com/2019/09/11/how-to-parse-json-in-net-core/
To do what MindingDate, suggested in his answer, in Text.Json you can utilize the JsonDocument class like so:
var myJsonString = File.ReadAllText("myfile.json");
var myJDoc = JsonDocument.Parse(myJsonString);
myJDoc.GetProperty("images")[*].GetProperty("url").ToString();

Substring a HTTP Response into a Variable [C# Winforms]

Im trying to get a cryptocurrency last price value from a HTTP API:
The following piece of code:
// Create the web request
HttpWebRequest request =
WebRequest.Create("APISITE") as
HttpWebRequest;
// Get response
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
// Console application output
currentXRPPrice.Text = (reader.ReadToEnd());
}
Gives me the following response which is correct:
{"high": "1.15600", "last": "1.08269", "timestamp": "1518697359", "bid": "1.08034", "vwap": "1.09634", "volume": "40858340.75727354", "low": "1.03051", "ask": "1.08269", "open": "1.13489"}
What I want is just the value of "last" which is "1.08269".
I have tried using this post: [link] (Remove characters after specific character in string, then remove substring?)
which has worked wonders for me on previous projects. But I cant seem to figure out where I am going wrong.
Iv tried below to get the value of "last" but its completely wrong, I have tried many of the different combinations to get it right but its not working to show me just the value for "Last".
response = currentXRPPrice.Text;
response = response.Remove(response.LastIndexOf(":") + 1);
profitLossText.Text = response; //Still wrong tried 4 combinations none work.
Thanks for any help!
You need to install Newtonsoft.Json from Nuget packages and use Parse method from JObject:
var lastValue = JObject.Parse(currentXRPPrice.Text).SelectToken("last").ToString();
First of all, if you have Json string, you can define a class which represent this object and then you just deserialize this string to object using generic method.
var jsonString = currentXRPPrice.Text;
var deserializedResponse = JsonConvert.DeserializeObject<ReponseType>(jsonString);
var lastValue = deserializedResponse.Last;
public class ReponseType
{
...
public float Last { get; set; }
...
}
You can do it by Regex too:
var lastValue = Regex.Match(jsonString, #"last\": \"(\\d+\\.\\d+)"").Groups[0];

Values from JSON formatted string (from REST API) in C#

Recently I got an appointment where I need to download some data from Cloud using it's REST API and store the values from that "string" in an object or in some variables. The download is done, all I need to do now is to parse somehow the data.
Until now i made this kind of code:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("some link");
request.ContentType = "application/json; charset=utf-8";
request.Method = "GET";
request.Headers.Add("Carriots.apiKey", "key");
using (WebResponse response = request.GetResponse())
{
using(Stream stream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(stream);
JObject json = JObject.Parse(reader.ReadToEnd());
Console.WriteLine(json.ToString());
}
}
And here is the output:
{
"total_documents": 3,
"result": [
{
"_id": "...",
"protocol": "v1",
"checksum": "",
"_t": "str",
"at": 1444134377,
"device": "-just a device-",
"data": {
"field1": "123",
"field2": "1536"
},
"id_developer": "....",
"created_at": 1444134377,
"owner": "-someUser-"
}
]
}
I know that there are a lot of solutions on the internet, but none of them does what I need. Okay, I found something, but that iterates on every line and checks the values that way, but in my case I can have thousands of outputs like this.
Are there any ways to do all that (I mean the parsing) using some kind of built-in functions or the only solution is to iterate or write some regular expression?
assuming the json will always follow this format, define your model
public class jsonData{
public int total_documents {get;set;}
public resultData result {get;set;}
}
public class resultData{
public int _id {get;set;}
public string protocol {get;set;}
....
}
then use deserialize
Json.Deserialize<jsonData>(yourstring)

how to split json format string in order to Deserialize is into .net object?

The subject sounds unclear, but the logic is very simple. I have a returned response data that is in json format. I want to Deserialize it into .net object which I defined already. I use JavaScriptSerializer class Deserialize method, it requires the parameter to be string. Now my response data is in json format, and has more than one roots.
My code is
WebRequest request = WebRequest.Create ("https://xxx.xxxxxx.com/xxxxx");
request.Method = "GET";
request.ContentType = "application/json";
var response = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
var responseText = streamReader.ReadToEnd();
}
The responseText value is
[
{
"webinarKey":5303085652037254656,
"subject":"Test+Webinar+One",
"description":"Test+Webinar+One+Description",
"organizerKey":73563532324,
"times":[{"startTime":"2011-04-26T17:00:00Z","endTime":"2011-04-26T18:00:00Z"}]
},
{
"webinarKey":9068582024170238208,
"name":"Test+Webinar+Two",
"description":"Test Webinar Two Description",
"organizerKey":73563532324,
"times":[{"startTime":"2011-04-26T17:00:00Z","endTime":"2011-04-26T18:00:00Z"}]
}
]
I use following code to deserialize responseText to a .net object that I defined.
JavaScriptSerializer ser = new JavaScriptSerializer();
Webinar w=ser.Deserialize<Webinar>(responseText);
Error comes out says responseText is an array, not string.
Then how to split responseText? I don't think it is appropriate to use string.split() method here.
Your response text is indeed a json array (containing 2 elements), as indicated by the [ and ] characters. Try the following:
Webinar[] w=ser.Deserialize<Webinar[]>(responseText);
Have you tried: List<Webinar> w=ser.Deserialize<List<Webinar>>(responseText);?

Categories

Resources