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

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();

Related

C# Rest Response in JSON Deserialize to Custom Object

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; }

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];

C# eBay API Upload Return Label

I haven't been able to figure out how to properly upload a label onto eBay using the /post-order/v2/return/{returnId}/file/upload call. I keep getting "The remote server returned an error: (400) Bad Request.".
I believe it may have to do with the image encoding, but I am not entirely certain. I was already able to approve the return with POST /return/{returnId}/decide but the next step in uploading is the problem. I have the image data saved as a base 64 string in a database. I know the data is good, because in other calls I am able to transform that base 64 string into an image in my application. So the data from the image isn't in question. The thing is on http://developer.ebay.com/Devzone/post-order/post-order_v2_return-returnId_file_upload__post.html#samplesellerlabel it states that the image data should be "base64-encoded binary representation of the file".
So is it possible that the data I received when grabbing the image with Convert.ToBase64String(imageBytes) is not what I actually need? There are little to no examples on how to do this particular call in C# and I've tried so many things. I've checked the JSON syntax and it looks to be correct. (I've removed a large portion of the string as it is too large.)
{"fileName":"5074119065_shippingLabel.jpeg","data":"R0lGODlhCAewBIEAAAAAAP///wAAAAAAACH/C05...zR2On54kkB4nfJYrLFRAAOw==","filePurpose":"LABEL_RELATED"}
I'm fairly convinced that the image data is somehow not formatted correctly, but I'm just not sure. If anyone has any experience with this call I'd appreciate your help. Below is my code and the error comes up on the last line. The headers and the JSON code has worked without any issues on other eBay calls which is also a reason I suspect my problem may have to do with the formatting of the image data.
string url = "https://api.ebay.com/post-order/v2/return/" + returnId + "/file/upload";
var cancelOrderRequest = (HttpWebRequest)WebRequest.Create(url);
cancelOrderRequest.Headers.Add("Authorization", "TOKEN " + authToken);
cancelOrderRequest.ContentType = "application/json";
cancelOrderRequest.Accept = "application/json";
cancelOrderRequest.Headers.Add("X-EBAY-C-MARKETPLACE-ID", "EBAY_US");
cancelOrderRequest.Method = "POST";
string fileName = returnId + "_shippingLabel.jpeg";
using (var streamWriter = new StreamWriter(cancelOrderRequest.GetRequestStream()))
{
string json = "{\"fileName\":\"" + fileName + "\",\"data\":\"" + labelData + "\",\"filePurpose\":\"LABEL_RELATED" + "\"}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
var response = (HttpWebResponse)cancelOrderRequest.GetResponse();
Hmm. The eBay documentation appears to be inconsistent. In the top part of the documentation page you linked for the Upload Return File method call, it seems to indicate that the data part of the JSON should be an array of strings, not just a single string.
Payload model
The following lists all fields that could be included in the request.
{ /* UploadFileRequest */
"data": [
string
/* More string nodes here */
],
"fileName": string,
"filePurpose": token
}
But in the JSON sample they show on the same page, the data is clearly a single string like you have it in your code. (Notice the square brackets are missing.)
URL format. See also the non-wrapped version of this URL.
POST https://api.ebay.com/post-order/v2/return/5000124931/file/upload
{
"fileName" : "jasmine.jpeg",
"data" : "SGVyZSBpcyB5b3VyIHJld...YWNraW5nIG51bWJlciBpcyAxMjM0NTY3ODk4NzY1",
"filePurpose" : "ITEM_RELATED"
}
I would try changing it to an array to match the documented payload. I'm guessing the sample is probably wrong here.
Also, I would highly recommend using a JSON serializer like Json.Net rather than hand-rolling your own JSON, as it is very easy to get the formatting wrong, which will just end up giving you more "400 Bad Request" headaches. Instead, try making the JSON by using an anonymous object and then serializing it, like this:
var payload = new
{
fileName = returnId + "_shippingLabel.jpeg",
data = new List<string> { labelData },
filePurpose = "LABEL_RELATED"
};
string json = JsonConvert.SerializeObject(payload);

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);?

Open webpage programmatically and retrieve its html contain as a string

I have a facebook account and I would like to extract my friend's photo and its personal detail such as "Date of birth", "Studied at" and so on. I am able to extract the address of the facebook's first page for each of my friends account but I don't know how to programmatically open webpage for each of my friends first page and save the html contain as a string so that I can extract out their personal detail and photos. Please help! Thank in advance!
You have Three options:
1- Using a WebClient object.
WebClient webClient = new webClient();
webClient.Credentials = new System.Net.NetworkCredential("UserName","Password", "Domain");
string pageHTML = WebClient .DownloadString("http://url");`
2- Using a WebRequest. This is the best solution because it gives you more control over your request.
WebRequest myWebRequest = WebRequest.Create("http://URL");
WebResponse myWebResponse = myWebRequest.GetResponse();
Stream ReceiveStream = myWebResponse.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader readStream = new StreamReader( ReceiveStream, encode );
string strResponse=readStream.ReadToEnd();
StreamWriter oSw=new StreamWriter(strFilePath);
oSw.WriteLine(strResponse);
oSw.Close();
readStream.Close();
myWebResponse.Close();
3- Using a WebBrowser (I bet you don't wanna do that)
WebBrowser wb = new WebBrowser();
wb.Navigate("http://URL");
string pageHTML = "";
wb.DocumentCompleted += (sender, e) => pageHTML = wb.DocumentText;
Excuse me if I misstyped any code because I improvised it and I don't have a syntax checker to check its correctness. But I think it should be fine.
EDIT: For facebook pages. You may consider using facebook Graph API:
http://developers.facebook.com/docs/reference/api/
Try this:
var html = new WebClient()
.DownloadString("the facebook account url goes here");
Also, once you have downloaded the HTML as a string I would highly recommend that you use the Html Agility Pack to parse it.
There are in general 2 things you can do here. The first thing you can do is called web scraping. That way you can download the source of the html with the following code:
var request = WebRequest.Create("http://example.com");
var response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream);
string stringResponse = reader.ReadToEnd();
}
stringResponse then contains the Html source of the website http://example.com
However, this is probably not what you want to do. Facebook has an SDK that you can use to download this kind of information. You can read about this on the following pages
http://developers.facebook.com/docs/reference/api/user/
If you want to use the FaceBook API then I think it's worth changing your question or asking a new question about this, since it's quite more complicated and requires some autorization and other codings. However, it's the best way since it's unlikely that your code is every going to break and it warrents the privacy of the people you want to get information from.
For example, if you query me with the api, you get the following string:
{
"id": "1089655429",
"name": "Timo Willemsen",
"birthday": "08/29/1989",
"education": [
{
"school": {
"id": "115091211836927",
"name": "Stedelijk Gymnasium Arnhem"
},
"year": {
"id": "127668947248449",
"name": "2001"
},
"type": "High School"
}
]
}
You can see that I'm Timo Wilemsen, 21 years old and studyied # Stedelijk Gymnasium Arnhem in 2001.
Use selenium 2.0 for C#. http://seleniumhq.org/download/
var driver = new FirefoxDriver();
driver.Navigate().GoToUrl("http://www.google.com");
String pageSource = driver.PageSource;

Categories

Resources