I want to deserialize a Json string from a php website. Unfortunately every time I try it, it will return null for medianPrice....Why?
public class PriceInfo
{
public string success { get; set; }
public double lowestPrice { get; set; }
public string volume { get; set; }
public string medianPrice { get; set; }
}
WebClient client = new WebClient();
string url = "http://steamcommunity.com/market/priceoverview/?country=US¤cy=1&appid=730&market_hash_name=" + name;
byte[] html = client.DownloadData(url);
UTF8Encoding utf = new UTF8Encoding();
string return_value = utf.GetString(html);
PriceInfo priceInfo = new JavaScriptSerializer().Deserialize<PriceInfo>(return_value);
if( Double.Parse(priceInfo.medianPrice) > 0.15 )
{
string blablu = "hello";
}
The Json which returns from the website is the following:
{"success":true,"lowest_price":"$0.04","volume":"3,952","median_price":"$0.02"}
I hope you can help me!
I am strongly recommending that you try using Newtonsoft.Json
you will find that it is easier to handle your Jason objects
your code will be like this (Untested)
PriceInfo defaultCallResult = JsonConvert.DeserializeObject<PriceInfo>(return_value);
Your JSON property is named "median_price" (with an underscore), but your C# property is "medianPrice".
You could use Json.NET which will allow you to change the mapping using attributes.
Using Json.NET, decorate your medianPrice property as follows:
[JsonProperty(PropertyName = "median_price")]
public string medianPrice { get; set; }
I'm not sure how JavaScriptSerializer succeeds in parsing your class at all, as the keys hardly match match the class properties.
JavaScriperSerializer is obsolete, I'd recommend you use another serializer, such as Json.NET:
public class PriceInfo
{
[JsonProperty("success")]
public string Success { get; set; }
[JsonProperty("lowest_price")]
public double LowestPrice { get; set; }
[JsonProperty("volume")]
public string Volume { get; set; }
[JsonProperty("median_price")]
public string MedianPrice { get; set; }
}
And when you want to deserialize:
PriceInfo priceInfo = JsonConvert.DeserializeObject<PriceInfo>(returnValue);
First of all, as mentioned in the other answers, your property names do not match.
So take
public class PriceInfo
{
public string success { get; set; }
public string lowest_price { get; set; }
public string volume { get; set; }
public string median_price { get; set; }
}
edit: as mentioned by Yuval, you cannot use JsonProperty with JavaScriptSerializer so you need to stick with the property names from the json.
Then, there is currency information in the json. So you need to get rid of these:
string return_value = "{\"success\":true,\"lowest_price\":\"$0.04\",\"volume\":\"3,952\",\"median_price\":\"$0.02\"}";
string return_valueconverted = HttpUtility.HtmlDecode(return_value);
PriceInfo priceInfo = new JavaScriptSerializer().Deserialize<PriceInfo>(return_valueconverted);
priceInfo.lowest_price = priceInfo.lowest_price.TrimStart('$');
priceInfo.median_price = priceInfo.median_price.TrimStart('$');
As you can see, this does HtmlDecode these values and afterwards trims the dollar sign from the value.
See more about Html character set here:
http://www.w3.org/MarkUp/html-spec/html-spec_13.html
Related
I have JSON string results as follows.
In this response Sometimes sizeKey and sizeName properties are returned as a string. But sometimes both properties are returns inside an array as follows
I am using following code to convert it to object
var assets = jObject["assets"].Children().ToList();
foreach (var item in assets)
{
decorationAssets.Add(item.ToObject<AEDecorationAssets>());
}
And my AEDecorationAssets class is as follows.
public class AEDecorationAssets
{
public string Id { get; set; }
public string Url { get; set; }
public string[] Colors { get; set; }
public string FontKey { get; set; }
public string SizeKey { get; set; }
public string ViewKey { get; set; }
public string FontName { get; set; }
public int Rotation { get; set; }
public string SizeName { get; set; }
public string TextValue { get; set; }
public string EntityType { get; set; }
public string LocationCode { get; set; }
public string LocationName { get; set; }
public string TextEffectKey { get; set; }
public string TextEffectName { get; set; }
public string DecorationMethod { get; set; }
public string NumDecorationColors { get; set; }
}
At the time when "sizeKey" is an array, the above code gives an error. How can I resolve this issue? Is there any JSON property we can use to resolve it?
One way you can do it is by making your SizeKey type an object (i.e. public object SizeKey { get; set; }), then you can switch/case on item.ToObject<AEDecorationAssets>().SizeKey.GetType() to figure out how to handle it (i.e. if String do this, if JArray do that), etc.
If a JSON type is sometime an array, and sometimes a string, you can't really map it simply to a .NET type, as there is none that supports this behavior.
So first you need a datatype that can store this, like and string[] or List<string>.
It could be that JsonConvert will solve this automatically, but otherwise you'll need to write a custom ContractResolver or JsonConverter. Here you can detect if the source property is a string or array. If it's an array, you can use the default deserialization. If it is a string, you need to convert it to an array with a single value.
Simply get json result for which you want to create c# object and then you can valid json response from https://jsonlint.com/ and then you can create c# object of any type json response which you want through http://json2csharp.com. And after get c# object of your json response you only need to deserialization of your json response to c# object which you have created. which will return you expected result.
Is it possible to have JObject.Parse ignore missing fields?
From my example below you can see that I have declared a class Address and using JsonProperty to specifying alternate field names.
I have provided 3 examples, there are 3 JSON strings which have a slightly different structure, only Example 1 matches and returns an object, Examples 2 and 3 return a null because there is a missing field.
Is there a way to use other JsonProperty's to allow them to be ignored if not provided?
public class Address
{
[JsonProperty("flat_number")]
public string FlatNumber { get; set; }
[JsonProperty("house_number")]
public string HouseNumber { get; set; }
[JsonProperty("address")]
public string Address1 { get; set; }
[JsonProperty("address2")]
public string Address2 { get; set; }
[JsonProperty("town")]
public string Town { get; set; }
[JsonProperty("postcode")]
public string Postcode { get; set; }
}
private static T TryParse<T>(string json) where T : new()
{
var jSchemaGenerator = new JSchemaGenerator();
const string license = "license";
License.RegisterLicense(license);
var jSchema = jSchemaGenerator.Generate(typeof(T));
var jObject = JObject.Parse(json);
return jObject.IsValid(jSchema) ? JsonConvert.DeserializeObject<T>(json) : default(T);
}
//Example 1 with house_number and flat_number
const string json = "{\"house_number\":\"40\",\"flat_number\":\"82\",\"address\":\"Somewhere\",\"address2\":\"Over\",\"town\":\"There\",\"postcode\":\"ZZ991AA\"}";
//Example 2 with house_number but not flat_number
//const string json = "{\"house_number\":\"40\",\"address\":\"Somewhere\",\"address2\":\"Over\",\"town\":\"There\",\"postcode\":\"ZZ991AA\"}";
//Example 3 with flat_number but not house_number
//const string json = "{\"flat_number\":\"82\",\"address\":\"Somewhere\",\"address2\":\"Over\",\"town\":\"There\",\"postcode\":\"ZZ991AA\"}";
var tryParse = TryParse<AddressTest>(json);
if (tryParse != null)
{
}
You can use JsonSerializerSettings to perform this operation. This will ignore your
missing members.
var jsonSerializerSettings = new JsonSerializerSettings();
jsonSerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore;
JsonConvert.DeserializeObject<YourClass>(jsonResponse, jsonSerializerSettings);
If you json contains some key/value pair as dynamic means you don't know if these key/value pairs is exist in json or not
If your objects are not fixed and data must be configurable then Newtonsoft.json has one feature that to be use here and that is [JsonExtensionData]. Read more
Extension data is now written when an object is serialized. Reading and writing extension data makes it possible to automatically round-trip all JSON without adding every property to the .NET type you’re deserializing to. Only declare the properties you’re interested in and let extension data do the rest.
Now your house_number and flat_number will be collected in [JsonExtensionData] so you no need to handle missing fields anymore.
So your Address class will be
public class Address
{
[JsonExtensionData]
public IDictionary<string, JsonToken> extensionData { get; set; }
[JsonProperty("address")]
public string Address1 { get; set; }
[JsonProperty("address2")]
public string Address2 { get; set; }
[JsonProperty("town")]
public string Town { get; set; }
[JsonProperty("postcode")]
public string Postcode { get; set; }
}
After a little more digging I found a JsonProperty that allows nulls to be ignored, by applying NullValueHandling = NullValueHandling.Ignore to both FlatNumber and HouseNumber all examples return an object. Therefore modifying the Address class as per my example below works in conjunction with my original code.
public class Address
{
[JsonProperty("flat_number", NullValueHandling = NullValueHandling.Ignore)]
public string FlatNumber { get; set; }
[JsonProperty("house_number", NullValueHandling = NullValueHandling.Ignore)]
public string HouseNumber { get; set; }
[JsonProperty("address")]
public string Address1 { get; set; }
[JsonProperty("address2")]
public string Address2 { get; set; }
[JsonProperty("town")]
public string Town { get; set; }
[JsonProperty("postcode")]
public string Postcode { get; set; }
}
I have an HttpClient that makes a call to a REST API.
var response = await client.PostAsync("Payments/CreditCard", content);
var contents = await response.Content.ReadAsStringAsync();
When I read the content of the response as a string, I get the following result:
"\"{\\\"ssl_card_number\\\":\\\"41**********9994\\\",\\\"ssl_exp_date\\\":\\\"1219\\\",\\\"ssl_amount\\\":\\\"50.00\\\",\\\"ssl_salestax\\\":\\\"\\\",\\\"ssl_invoice_number\\\":\\\"\\\",\\\"ssl_departure_date\\\":\\\"\\\",\\\"ssl_completion_date\\\":\\\"\\\",\\\"Test\\\":\\\"\\\",\\\"TestField\\\":\\\"TestValue\\\",\\\"ssl_result\\\":\\\"0\\\",\\\"ssl_result_message\\\":\\\"APPROVAL\\\",\\\"ssl_approval_code\\\":\\\"578380\\\",\\\"ssl_cvv2_response\\\":\\\"U\\\",\\\"ssl_avs_response\\\":\\\"G\\\",\\\"ssl_account_balance\\\":\\\"0.00\\\",\\\"ssl_txn_time\\\":\\\"04/09/2018 09:41:01 AM\\\",\\\"ssl_card_type\\\":\\\"CREDITCARD\\\"}\""
When I debug and inspect the value of the contents variable, it contains the following:
When I try to deserialize the string into a C# object using JSON.Net, I receive an exception, because the contents variable can't be converted to my C# object.
However, if I take the string from the Text Visualizer, I'm able to successfully convert it to my C# object.
Here's the class I'm trying to deserialize the string contents into:
public class PaymentResponse
{
public string ssl_account_balance { get; set; }
public string ssl_amount { get; set; }
public string ssl_approval_code { get; set; }
public string ssl_avs_response { get; set; }
public string ssl_card_number { get; set; }
public string ssl_card_type { get; set; }
public string ssl_completion_date { get; set; }
public string ssl_cvv2_response { get; set; }
public string ssl_departure_date { get; set; }
public string ssl_exp_date { get; set; }
public string ssl_invoice_number { get; set; }
public string ssl_result { get; set; }
public string ssl_result_message { get; set; }
public string ssl_salestax { get; set; }
public string ssl_txn_id { get; set; }
public string ssl_txn_time { get; set; }
}
Here's the code I use for deserializing:
paymentResponse = JsonConvert.DeserializeObject<PaymentResponse>(contents);
How can I get my contents variable to have the same value that appears in the Text Visualizer?
The data shown appears to be serialized twice.
In that case it would need to be deserialized twice.
First to string,
var json = JsonConvert.DeserializeObject<string>(contents);
and then to the desired type
var paymentResponse = JsonConvert.DeserializeObject<PaymentResponse>(json);
#Nkosi was right: first deserialize it to string and then to PaymentResponse:
var contents = "\"{\\\"ssl_card_number\\\":\\\"41**********9994\\\",\\\"ssl_exp_date\\\":\\\"1219\\\",\\\"ssl_amount\\\":\\\"50.00\\\",\\\"ssl_salestax\\\":\\\"\\\",\\\"ssl_invoice_number\\\":\\\"\\\",\\\"ssl_departure_date\\\":\\\"\\\",\\\"ssl_completion_date\\\":\\\"\\\",\\\"Test\\\":\\\"\\\",\\\"TestField\\\":\\\"TestValue\\\",\\\"ssl_result\\\":\\\"0\\\",\\\"ssl_result_message\\\":\\\"APPROVAL\\\",\\\"ssl_approval_code\\\":\\\"578380\\\",\\\"ssl_cvv2_response\\\":\\\"U\\\",\\\"ssl_avs_response\\\":\\\"G\\\",\\\"ssl_account_balance\\\":\\\"0.00\\\",\\\"ssl_txn_time\\\":\\\"04/09/2018 09:41:01 AM\\\",\\\"ssl_card_type\\\":\\\"CREDITCARD\\\"}\"";
var contentAsString = JsonConvert.DeserializeObject<string>(contents);
var paymentResponse = JsonConvert.DeserializeObject<PaymentResponse>(contentAsString);
Console.WriteLine(paymentResponse.ssl_card_number);
Check the fiddle.
Here is the solution. Actually we need to take care about the Encoding while deserializing to object. Since the content string of the object would sometimes have other than ASCII charset. It worked fine for me.
var resultBytes = await response.Content.ReadAsByteArrayAsync();
var actualEncodedString = Encoding.UTF8.GetString(resultBytes);
var actualObject = JsonConvert.DeserializeObject<T>(actualEncodedString);
How can we parse if json fields contains a colon(:)? Like this:
{
"dc:creator":"Jordan, Micheal",
"element:publicationName":"Applied Ergonomics",
"element:issn":"2839749823"
}
In fact I wonder how to do this with a library like restsharp, for mapping?
Using Json.Net
string json = #"{
""dc:creator"":""Jordan, Micheal"",
""element:publicationName"":""Applied Ergonomics"",
""element:issn"":""2839749823""
}";
var pub = JsonConvert.DeserializeObject<Publication>(json);
public class Publication
{
[JsonProperty("dc:creator")]
public string creator { set; get; }
[JsonProperty("element:publicationName")]
public string publicationName { set; get; }
[JsonProperty("element:issn")]
public string issn { set; get; }
}
OR
Console.WriteLine(JObject.Parse(json)["dc:creator"]);
If you use DataContractJsonSerializer, DataMemberAttribute has property Name which can be used to override default name. This means that when you deserialize json value of property dc:creator is assigned to Publication::Creator property and on the contrary when you serialize C# object.
For example:
public class Publication
{
[DataMember(Name="dc:creator")]
public string Creator { set; get; }
[DataMember(Name="element:publicationName")]
public string PublicationName { set; get; }
[DataMember(Name="element:issn")]
public string Issn { set; get; }
}
If you choose to use Json.Net, #L.B's answer is the way to go.
I am helpless, I need deserialize JSON string in this format to class.
JSON string:
{
"newNickInfo": {
"2775040": {
"idUser": 2775040,
"nick": "minci88",
"sefNick": "minci88",
"sex": 2,
"photon": "http:\/\/213.215.107.125\/fotky\/277\/50\/n_2775040.jpg?v=4",
"photos": "http:\/\/213.215.107.125\/fotky\/277\/50\/s_2775040.jpg?v=4",
"logged": false,
"idChat": 0,
"roomName": "",
"updated": 1289670130
}
}
}
Class:
public class User
{
public string idUser { get; set; }
public string nick { get; set; }
public string sefNick { get; set; }
public string sex { get; set; }
public string photon { get; set; }
public string photos { get; set; }
public bool logged { get; set; }
public int idChat { get; set; }
public string roomName { get; set; }
public string updated { get; set; }
}
First problem is, class properties must be lower case, and second problem is I try many ways but I don’t know how cut json object from this json string and deserialize in class.
Any ides? Thank for any help.
One more question, what format would have c# class, if I want deserialize this json string into it.
looks like your JSON string is not correct. Look at this
string json = #"[
{
"newNickInfo": "2775040",
"idUser": "2775040",
"nick":"minci88",
"sefNick":"minci88",
"sex":2,
"photon":"http:\/\/213.215.107.125\/fotky\/277\/50\/n_2775040.jpg?v=4",
"photos":"http:\/\/213.215.107.125\/fotky\/277\/50\/s_2775040.jpg?v=4",
"logged":false,
"idChat":0,
"roomName":"",
"updated":"1289670130"
}
]";
public class User
{
[JsonProperty]
public string idUser{get;set;}
[JsonProperty]
public string nick{get;set;}
[JsonProperty]
public string sefNick{get;set;}
[JsonProperty]
public string sex{get;set;}
[JsonProperty]
public string photon{get;set;}
[JsonProperty]
public string photos{get;set;}
[JsonProperty]
public bool logged{get;set;}
[JsonProperty]
public int idChat{get;set;}
[JsonProperty]
public string roomName{get;set;}
[JsonProperty]
public string updated{get;set;}
}
List<User> users = JsonConvert.DeserializeObject<List<User>>(json);
User u1 = users[0];
Console.WriteLine(u1.nick);
using System.Web.Script.Serialization;
var serializer = new JavaScriptSerializer();
var deserialized = serializer.Deserialize<Dictionary<string, Dictionary<string, User>>>(theJsonString);
var theUser = deserialized["newNickInfo"]["2775040"];
I use this tool Jsonclassgenerator. It could generate C# classes for the input Json string. You dont have to use the exact class generated. But you can see the format of the class and create a similar one in your project.