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.
Related
I'm having a well-defined class for sending as JSON body in an HTTP request.
public class EventData
{
public string deviceJobId { get; set; }
public int eventID { get; set; }
public long time_ms { get; set; }
/// similar fields
}
Now I have to add one more field called HealthInfo. The value of this new HealthInfo is a nested JSON read from some file.
The fields of this JSON file change from time to time, and there is no guarantee that some fields will always be present.
I don't want to read/modify any value of that and just need to publish this EventData as a json as part of an HTTP request.
Then how to add HealthInfo correctly?
I tried to put HealthInfo as string and object is getting double serialized.
you have to convert to JObject before you add new json string
JObject jo = JObject.FromObject(eventData);
jo["HealthInfo"] = jsonStringHealthInfo;
//or it could be (your question needs some details)
jo["HealthInfo"]=JObject.Parse(jsonStringHealthInfo);
StringContent content = new StringContent(jo.ToString(), Encoding.UTF8, "application/json");
var response = await client.PostAsync(api, content))
If you know all of the possible properties inside HealthInfo then you can create new class HealthInfo with nullable properties.
public class HealthInfo
{
public string? SomeData { get; set; }
public int? SomeOtherData { get; set; }
}
and then add nullable HealthInfo in your main class:
public class EventData
{
public string deviceJobId { get; set; }
public int eventID { get; set; }
public long time_ms { get; set; }
public HealthInfo? HealthInfo { get; set; }
/// similar fields
}
However if you're not sure what kind of data you're gonna get and want to avoid double serialization, just pass HealthInfo as object:
public class EventData
{
public string deviceJobId { get; set; }
public int eventID { get; set; }
public long time_ms { get; set; }
public object? HealthInfo { get; set; }
/// similar fields
}
You can use of C# reflection. (TypeBuilder.DefineProperty Method)
In fact you must add prop to the class in run time.
see full information at
https://learn.microsoft.com/
This line is giving me the error
Cannot deserialize the current JSON object (e.g. {"name":"value"})
From other posts I gather I should not be putting this into a list. However This worked fine for me until I added the avgPx field.
How can I get this information into my List properly?
Does my list of type <OrderRecord> need to include all the fields returned by the JSON?
List<OrderRecord> orderRecord_Single = new List<OrderRecord>();//define and set to null
OrderRecord_Single = JsonConvert.DeserializeObject<List<OrderRecord>>(orderString);
This is one case of my jsonstring. It has the brackets on it.
"[{\"orderID\":\"5dcc6560-9672-958d-010b-7d18c9d523ab\",\"account\":1024235,\"symbol\":\"ETHUSD\",\"timestamp\":\"2020-04-26T18:21:05.703Z\",\"clOrdID\":\"\",\"side\":\"Buy\",\"price\":194.95,\"orderQty\":1,\"ordStatus\":\"New\",\"text\":\"ZT\",\"transactTime\":\"2020-04-26T18:21:05.703Z\",\"avgPx\":null}]"
public class OrderRecord
{
[JsonProperty("orderID")]
public string orderID { get; set; }
[JsonProperty("symbol")]
public string symbol { get; set; }
[JsonProperty("side")]
public string side { get; set; }
[JsonProperty("price")]
public string price { get; set; }
[JsonProperty("orderQty")]
public string orderQty { get; set; }
[JsonProperty("ordStatus")]
public string ordStatus { get; set; }
[JsonProperty("transactTime")]
public string transactTime { get; set; }
[JsonProperty("timestamp")]
public string timestamp { get; set; }
[JsonProperty("avgPx")]
public string avgPx { get; set; }
}
The error occurs because you are trying deserializing a JSON object to a JSON array. So you should provide a JSON array as in input. For the given JSON, add brackets [ ] to the first and last of the JSON string for creating valid JSON array:
var jsonString = "[{\"orderID\":\"8d853505-248d-e515-ee17-ddcd24b5fecb\",\"account\":1024235,\"symbol\":\"XBTUSD\",\"timestamp\":\"2020-04-20T18:25:07.601Z\",\"clOrdID\":\"\",\"side\":\"Buy\",\"price\":6885.5,\"orderQty\":8700,\"ordStatus\":\"Filled\",\"text\":\"ZT\",\"transactTime\":\"2020-04-20T18:22:11.135Z\",\"avgPx\":6885.5}]"
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 getting JSON that is being returned from a REST web service for survey responses. It has arrays for the name portion of some of the name value pairs. Additionally the names will be variable depending on the type of questions asked. I'm using JSON.net and trying to deserialize the returned value into some type of object tree that I can walk but can't figure out what structure to use to have it filled in.
I tested the following snippet in LinqPad and fields is always empty. Is there someway to easily read in the variable data or do I have to parse it in code?
void Main() {
string json = #"{
'result_ok':true,
'total_count':'51',
'data':[{
'id':'1',
'status':'Deleted',
'datesubmitted':'2015-01-12 10:43:47',
'[question(3)]':'Red',
'[question(4)]':'Blue',
'[question(18)]':12,
'[variable(\'STANDARD_IP\')]':'127.0.0.1',
'[variable(\'STANDARD_GEOCOUNTRY\')]':'United States'
}]
}";
var responses = JsonConvert.DeserializeObject<RootObject>(json);
responses.Dump();
}
public class RootObject {
public bool result_ok { get; set; }
public string total_count { get; set; }
public List<Response> data { get; set; }
}
public class Response {
public string id { get; set; }
public string status { get; set; }
public string datesubmitted { get; set; }
public List<object> fields = new List<object>();
}
Change the fields property in your Response class to be a Dictionary<string, object>, then mark it with a [JsonExtensionData] attribute like this:
public class Response
{
public string id { get; set; }
public string status { get; set; }
public string datesubmitted { get; set; }
[JsonExtensionData]
public Dictionary<string, object> fields { get; set; }
}
All of the fields with the strange property names will then be placed into the dictionary where you can access them as normal. No extra code is required.
Here is a demo: https://dotnetfiddle.net/1rQUXT
Need to convert JSON string into C# object.
say,
List<PerMeterCosts> myDeserializedObjList = (List<PerMeterCosts>)Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString, typeof(List<PerMeterCosts>));
trying to Replacing string so that it can be de-serialized according to distinguished object.
[{"PerMeterCostID":"","DrillBitSizeID":"","Form":"5656","To":"5656","PerMeterCost":"5656","ContractID":""},{"PerMeterCostID":2280,"DrillBitSizeID":10,"ContractID":1,"Form":"05656","To":200,"PerMeterCost":79.41}]
want to have replaced "" with "0".I think after replacing that it would be suitable for de-serialize.
how could I do that?
If u don't know the content u can just ether setup your properties like this :
If it sometimes returns a string and sometimes an int u just set the type to object
public object PerMeterCostID { get; set; }
public object DrillBitSizeID { get; set; }
public string Form { get; set; }
public object To { get; set; }
public object PerMeterCost { get; set; }
public object ContractID { get; set; }