I have a Python code that sends this JSON through MQTT.
message = {
"name":"Alex",
"date": 2021,
"activity":["act1","act2","act3"],
}
Then I receive and Deserialize it in a C# script
public void Client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
{
var Message = System.Text.Encoding.Default.GetString(e.Message);
Dictionary<string, string> MessageDICT = JsonConvert.DeserializeObject<Dictionary<string, string>>(Message);
}
The keys "name" and "date" has no problem being deserialized into the dictionary. However the error comes with "activity" due it being an array. Where it states "Unexpected character encountered while parsing value:[". I have seen methods where they deserialize it separately (where the array is sent in a different message), however this is not what I want. Is there a way I can deserialize the message as a whole?
Thanks.
You have your dictionary declared as <string, string>, but "activity" is an array. So this is why it does not work.
If you want to keep using a dictionary, then you can instead declare it as <string, object> and then it will work for any type of data. But you will need to then check what Type it is before you later try to use it.
Dictionary<string, object> MessageDICT = JsonConvert.DeserializeObject<Dictionary<string, object>>(message);
You can then access it like this:
object first = ((JArray)MessageDICT["activity"])[0];
But if possible, you should try to use a fixed class for the data and deserialize that.
Otherwise, maybe a dynamic is better.
Hi why not use a class to read the json
public class Message
{
public string name {get;set;}
public string date {get;set;} //actually, this looks like an int the json, however...
public string[] activity {get;set;}
}
usage
var res = JsonConvert.DeserializeObject<Message>(message);
Related
Let's say I have a json like this
"inventory":{
"sh0001":{
"price":100
},
"sh0002":{
"price":50
}
}
And I want to deserialize it with Json.net, into a data structure like this
class Store
{
public Dictionary<string, Item> inventory;
}
class Item
{
[JsonIgnore] public string id;
public int price;
}
I want to use the dictionary key (e.g. "sh0001") and assign them to the value object's Id variable (item.id = "sh0001").
One obvious solution is to add a method like Store.OnJsonDeserialized(), and maybe call it within a factory method Store.FromJson(string json), such that we won't forget to and call it after Deserialization...
public void OnJsonDeserialized()
{
foreach(var kvp in inventory)
kvp.value.id = kvp.key;
}
public static Store FromJson(string json)
{
var newObj = JsonConvert.DeserializeObject<Store>(json);
newObj.OnJsonDeserialized();
return newObj;
}
But what if we now want to Embed the Store class into another class (e.g. Company), and deserialize that from JSON instead?
class Company
{
public Store[] stores;
}
Now JsonConvert.DeserializeObject<Company>(json) will not work as intended, and item.Id won't be assigned.
Is there any better way to do the Deserialization in this case?
Thank you.
Immediately after typing the question, I figure out that the Json.net supports a few serialization callback attributes (from System.Runtime.Serialization), which is exactly what I need.
[OnDeserialized]
internal void OnDeserializedMethod(StreamingContext context)
{
Member4 = "This value was set after deserialization.";
}
Alternatively, instead of using a Dictionary, there's also KeyedCollection<TKey,TItem>, which reduces the need for duplicated dictionary key. The downside is that it won't deserialize and serialize to the desired json format I want by default, and require some customization.
I have a massive json file that i am parsing. But I have a problem when parsing it.
There is a field in the file that looks similar:
"pageTitle": {
"en": "Some content here...."
},
I store this as a dictionary:
[JsonProperty("pageTitle")]
public Dictionary<string, string> PageTitle { get; set; }
But sometimes this field is empty, and when it is the Json.Net method
ToObject<MyCustomClass>()
Fails when trying to convert pageTitle because it appears to be an empty array and not an object. Is there a JsonPropery to make it ignore this empty array and just carry on?
If you would like to ignore the null values, then it is possible to decorate the property as follows:
[JsonProperty("pageTitle", NullValueHandling = NullValueHandling.Ignore)]
If the JSON string being parsed is an empty array [] or an invalid input, you might have to write a custom converter by extending the abstract class, JsonConverter or extending one of the inbuilt converters in Newtonsoft.Json.Converters and invoke it as:
var obj = JsonConvert.DeserializeObject<MyCustomClass>(jsonString, new CustomConverter());
OR
Handle the exception that happens during deserialization as follows:
var obj = JsonConvert.DeserializeObject<MyCustomClass>(json, new
JsonSerializerSettings
{
Error = HandleError
});
Handler:
private static void HandleError(object sender, ErrorEventArgs e)
{
// Get the error message using 'e.ErrorContext.Error.Message'
// e.ErrorContext.OriginalObject will give you the object/property that failed to deserialze
e.ErrorContext.Handled = true;
}
I have to extract a part of json-string using .net or newtonsoft json.
JSON:
var json = "{\"method\":\"subtract\",\"parameters\":{\"minuend\":\"SOME_CUSTOM_JSON_OBJECT_DIFFERENT_FOR_EACH_METHOD\",\"subtrahend\":23}}";
C# Class:
class MyJson{
public string method { get; set; }
//public string parameters {get; set;}
public object parameters {get; set;}
}
I do not need to parse all the children of "parameters" json-object. "parameters" could be a very big object ([{obj1}...{obj1000}], objX of 1000 fields), parse which would be not performant.
I would like i.e. to pass it exactly as it is on some point, so conversion "string-C#object-string" would be redundant.
I do not want use Regexp or string transformations (string.Substring, Split and co), because of error margin, I know that all .net and newtonsoft string transformations based.
Question 1: if I define a property of type "object", how newtonsoft will handle this? (Documentation is worse than msdn, so I'm looking for the input from you, who already tried this).
static void Main(string[] args)
{
var json = "{\"method\":\"subtract\",\"parameters\":{\"minuend\":42,\"subtrahend\":23}}";
var data = JsonConvert.DeserializeObject<MyJson>(j);
// what internal representaion of data.parameters?
// How is it actually converted from json-string to an C# object (JObject/JsonObject).
}
In perfect case:
"parameters" is a string and calling
ExtractMyJson(jsonString)
gives me the json string of parameters.
Basically I need the newtonsoft version of
string ExtractMyJson(jsonString){
var p1 = jsonString.Split(",");
// .. varios string transformations
return pParams;
}
Note: please don't reference "dynamic" keyword or ask why no string transformations, it's the very specific question.
If you know that your parameters are unique you can do something like this:
class MyJson
{
public string method { get; set; }
public Dictionary<string,object> parameters { get; set; }
}
................
string json = "{\"method\":\"subtract\",\"parameters\":{\"minuend\":{\"img\": 3, \"real\": 4},\"subtrahend\":23}}";
var data = JsonConvert.DeserializeObject<MyJson>(json);
If you let it as object is going to receive the type Newtonsoft.Json.Linq.JObject.
Have you tried JTOKEN?
It is a rather simple solution to partially read basic or nested JSONs as described in this post.
For a nested JSON
{
"key1": {
"key11": "value11",
"key12": "value12"
}
"key2": "value2"
}
it would look like this
JToken token = JToken.Parse(json);
var value12 = token.SelectToken("key1.key12");
to get the element of the key "key12.
I think this could go nicely with your problem.
Well Objects are treated the same way your parent object is treated. It will start from the base of the graph. So if you have something like:
Person
{
Address Address {get;set;}
}
The Json will start Deserializing Address and then add in the Person object.
If you want to limit thesize of the graph depth you can use a setting like :
JsonConvert.DeserializeObject<List<IList<IList<string>>>>(json, new JsonSerializerSettings
{
MaxDepth = 2
});
For more configurations of the JsonSerializer check JsonSerializerSettings
If your field is an object then that object will have the KeyValuePair of every property that it holds, based on that when you cast that field you can access that type.(the behaviour is the same as assigning a type to an object in C#).
Update: So if you question using JsonObject or type, well JObject is and intermediary way to construct the json format in a generic format. But using the Type deserializatin means you can ignore properties you are not interested in. Mapping to a json with a type makes more sense because it creates a new object and dismisses the old JObject.
I'm really bad with C# and would like your help doing the following; I am currently passing a Json Array to my WCF webservice. I need to take the json array and insert it into a list. I have no idea to deserialize in C#. Please suggest to me what is the best way of achieving this. My code looks as follows:
public String UpdateOrderAddress(Stream userInfo)
{
try
{
StreamReader reader = new StreamReader(userInfo);
string JSONdata = reader.ReadToEnd();
if (JSONdata == null)
{
return "null";
}
return JSONdata; // Success !
}
catch (Exception e)
{
return e.ToString();
}
}
This is the data in the string that I get from the reader
[{"date":"2013-02-22 15:30:374:021","id":"1","description":"test","name":"test"},
"date":"2013-02-25 11:56:926:020","id":"2","description":"ghy","name":"fhh"},
"date":"2013-02-25 11:56:248:026","id":"3","description":"ghfm","name":"run"}]
The code you posted doesn't show how are you trying to deserialize your json string so I don't really follow what's the relevance here but in any case, this is how to deserialize JSON into a concrete C# class.
Create a class that matches the structure of your Javascript objects as so:
public class Data
{
public string Date {get;set;}
public int ID {get;set;}
public string Description {get;set;}
public string Name {get;set;}
}
Deserialize it using the JavascriptSerializer as so:
var deserializedData = new JavaScriptSerializer().Deserialize<List<Data>>(jsonString);
Note that your original JSON string is incorrectly formatted. It's missing the opening { on each element of the array. It should really be:
[{"date":"2013-02-22
15:30:374:021","id":"1","description":"test","name":"test"},
{"date":"2013-02-25
11:56:926:020","id":"2","description":"ghy","name":"fhh"},
{"date":"2013-02-25
11:56:248:026","id":"3","description":"ghfm","name":"run"}]
Now, if you attempt to deserialize the above, as so:
string json = #"[{""date"":""2013-02-22 15:30:374:021"",""id"":""1"",""description"":""test"",""name"":""test""},
{""date"":""2013-02-25 11:56:926:020"",""id"":""2"",""description"":""ghy"",""name"":""fhh""},
{""date"":""2013-02-25 11:56:248:026"",""id"":""3"",""description"":""ghfm"",""name"":""run""}]";
var deserializedData = new JavaScriptSerializer().Deserialize<List<Data>>(json);
You'll get a nice List<Data> back.
Also note that I didn't use a DateTime field for the corresponding date field in your Javascript object, the reason being that your sample dates are not valid DateTimes or at least a DateTime object cannot be created from that string representation. For instance, "15:30:374:021" makes no sense - I would imagine that 374 is the seconds field...
You need to add a reference to System.Web.Extensions to be able to use the JavascriptSerializer.
You can create a representative class with your required properties to hold the values and use the JavascriptSerializer class. Call the Deserialize<T> method specifying your type to deserialize the JSON into your code.
Links in class names for reference.
You can use Newtonsoft.Json Library. All you will need to do is:
List<YourClass> yourClassList = JsonConvert.DeserializeObject<List<YourClass>>(JSONdata);
You find more information, even samples here
I'm recieving a JSON object that looks like the example below.
{
"name1":{"name1a":"value1a","name1b":"value1b"},
"name2":{"name2a":"value2a","name2b":"value2b"}
}
I've set up a data contract for it (since I only need to access a single data field at the moment) like this.
[DataContract]
public class MyThingy
{
[DataMember(Name="name1b")]
public string Name1b { get; set; }
public MyThingy() { }
public MyThingy(String name1b)
{
Name1b = name1b;
}
}
When I've serialized the object, I try to print it out (which works, since I'm getting a string description of the class) and them the field Name1b. The last part doesn't work and I'm getting null there. My guess is that I must have mapped the data contract wrongly but I can't see how to correct it.
How should the MyThingy class be declared?
My JSON object is fetched as described in this post.
I would use JavaScriptSerializer here,
string json = #"{
""name1"":{""name1a"":""value1a"",""name1b"":""value1b""},
""name2"":{""name2a"":""value2a"",""name2b"":""value2b""}
}";
var obj = new JavaScriptSerializer()
.Deserialize<Dictionary<string, Dictionary<string, string>>>(json);
Console.WriteLine(obj["name1"]["name1b"]);
You can also use Json.Net and dynamic together
dynamic obj = JsonConvert.DeserializeObject(json);
Console.WriteLine(obj.name1.name1b);