How to only serialize a special property's value to json - c#

YamlDotNet can deserialize a yaml document which contain json.
Suppose there is a yaml document as input like below.
fieldA: a
fieldB:
- { "subFieldA": "a1","subFieldB": "b1" }
- { "subFieldA": "a2","subFieldB": "b2" }
Then, I deserialize it and re-serialize.
class Program
{
static void Main(string[] args)
{
using var sr = new StreamReader("test.yaml");
var deserializer = new DeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.Build();
var output = deserializer.Deserialize<Temp>(sr);
var serializer = new SerializerBuilder()
.Build();
Console.WriteLine(serializer.Serialize(output));
}
}
public class Temp
{
public string FieldA { get; set; }
public List<Dictionary<string, string>> FieldB { get; set; }
}
I would get output like below.
FieldA: a
FieldB:
- subFieldA: a1
subFieldB: b1
- subFieldA: a2
subFieldB: b2
But I want the property FieldB still be serialized to json.
In other words, I want to get a output same as input.
Is there a way to use YamlDotNet to achieve this effect, please?

YamlDotNet is only used for serializing and deserializing YAML. Use the .NET serialization library if all you want to do is actually serialize that dictionary. Obviously the string property cannot do anything with unless it's part of the dictionary.
using System.Text.Json;
var temp = new Temp();
temp.Dict = new Dictionary<string, string>();
temp.Dict.Add("hello", "world");
string json = JsonSerializer.Serialize(temp.Dict);
If you're asking if you can put JSON into YAML, sure, just turn it into a json string first, and add that string as a property of a separate class to serialize into YAML. I don't believe there's a way to automatically get a YAML library to be serializing portions of its stuff into JSON. You can't mix and match.

Related

Is there a way to deserialize only a single JSON field [duplicate]

So I have a JSON string where I just want to read a specific value. How do I just pick "Read me please!" from string below?
var readString = /*Read me please!*/
JSON string:
"{\"aString\":\"Read me please!\"}"
For better understanding, how do I do the same here? (just "Read me please!"):
"{\"Result\":
{
\"aString\":\"Read me please!\",
\"anotherString\":\"Dont read me!\"
}
}"
If both alternative have different solution I would like to know both.
PS: I do not wish to save the value into object/class or so. Just temporary inside var readString.
You could write a model:
public class MyModel
{
public string AString { get; set; }
}
and then use a JSON serializer such as Json.NET:
string readString = "{\"aString\":\"Read me please!\"}";
MyModel model = JsonConvert.DeserializeObject<MyModel>(readString);
Console.WriteLine(model.AString);
If you don't want to use third party solutions you could use the built-in JavaScriptSerializer class:
string readString = "{\"aString\":\"Read me please!\"}";
MyModel model = new JavaScriptSerializer().Deserialize<MyModel>(readString);
Console.WriteLine(model.AString);
Now assuming you want to handle your second JSON string you could simply adapt your model:
public class Wrapper
{
public MyModel Result { get; set; }
}
public class MyModel
{
public string AString { get; set; }
public string AnotherString { get; set; }
}
and then deserialize to this wrapper class:
string readString = ... the JSON string in your second example ...;
Wrapper wrapper = JsonConvert.DeserializeObject<Wrapper>(readString);
Console.WriteLine(wrapper.Result.AString);
Console.WriteLine(wrapper.Result.AnotherString);
UPDATE:
And if you don't want to deserialize to a model you could directly do this:
string readString = "{\"aString\":\"Read me please!\"}";
var res = (JObject)JsonConvert.DeserializeObject(readString);
Console.WriteLine(res.Value<string>("aString"));
or with the built-in JavaScriptSerializer class:
string readString = "{\"aString\":\"Read me please!\"}";
var serializer = new JavaScriptSerializer();
var res = (IDictionary<string, object>)serializer.DeserializeObject(readString);
Console.WriteLine(res["aString"]);
var readString = JObject.Parse(str)["aString"];
Or for your second example:
var readString2 = JObject.Parse(str2)["Result"]["aString"];
Json.NET also provides a JSON reader if you don't want to deserialize the whole thing. For example:
string json = "{\"Result\": { \"aString\":\"Read me please!\", \"anotherString\":\"Dont read me!\" } }";
using (var reader = new JsonTextReader(new StringReader(json)))
{
while (reader.Read())
{
if (reader.TokenType == JsonToken.PropertyName && (string)reader.Value == "aString")
{
reader.Read();
Console.Write(reader.Value);
break;
}
}
}
Console.ReadKey();
You have to use Newtonsoft (JSON.NET) to accomplish that. Then, you can access your json property this way:
var obj = JsonConvert.DeserializeObject(yourJson);
Console.WriteLine(obj.Result.aString);
I played around with writing a generic method that can read any part of my json string. I tried a lot of the answers on this thread and it did not suit my need. So this is what I came up with. I use the following method in my service layer to read my configuration properties from the json string.
public T getValue<T>(string json,string jsonPropertyName)
{
var parsedResult= JObject.Parse(json);
return parsedResult.SelectToken(jsonPropertyName).ToObject<T>();
}
and this is how you would use it :
var result = service.getValue<List<string>>(json, "propertyName");
So you can use this to get specific properties within your json string and cast it to whatever you need it to be.

Unable to deserialize Json string array of arrays into object when using Newtonsoft.Json

i am using Newtonsoft.Json and trying to deserialize an array of arrays Json string into C# object i created.
This is the json string -
[4615,4618,4619,4626,4615,4626,4631,4636,4637],[4615,4618,4619,4626,4615,4626,4631,4636,4637],[4615,4618,4619,4626,4615,4626,4631,4636,4637]
This is my object model -
public class NumberMatrix
{
public List<int> NumberIDs { get; set; }
public NumberMatrix()
{
this.NumberIDs = new List<int>();
}
}
This is how i try to convert -
var numbers = HttpContext.Current.Request.Params["Numbers"];
var numberIDsMatrix = JsonConvert.DeserializeObject<List<NumberMatrix>>(numbers);
i tried to deserialize the json in few ways, and got different errors. is it possible to deserialize this json string? how?
That isn't valid JSON, you need to surround it with [...] for example. You could do this:
var result = JsonConvert.DeserializeObject<List<List<int>>>($"[{numbers}]");

Parsing JSON list to int array in c#

I'm having trouble reading a JSON list of numbers into a c# int[] array.
I've tried several suggestions from SO, but none have worked.
How would I go about this using JSON.net?
Extract from JSON file:
{
"course": "Norsk",
"grades": [6, 3, 5, 6, 2, 8]
}
What I've tried in c#:
// Reads the JSON file into a single string
string json = File.ReadAllText(jfile);
Console.WriteLine(json);
// Parsing the information to a format json.net can work with
JObject data = JObject.Parse(json);
JToken jToken = data.GetValue("grades");
jGrades = jToken.Values<int>().ToArray();
and:
// Reads the JSON file into a single string
string json = File.ReadAllText(jfile);
Console.WriteLine(json);
// Parsing the information to a format json.net can work with
JObject data = JObject.Parse(json);
for (int o = 0; o < 6; o++) {
var grades = from p in data["Info"[i]] select (int)p["grades"[o]];
jGrades.Add(Convert.ToInt32(grades));
}
As you can see from the c# extracts, I've tried with both arrays and lists, but I can't get it to work.
With the first example (with an array) I get a System.NullRefrenceException, while with the List example, I get several errors, such as Unable to cast object of type 'whereselectlistiterator'2 [Newtonsoft.JSON] to type 'system.iconvertible'
Any help of tips are appreciated.
JObject.Parse(json) is your root object
JObject.Parse(json)["grades"] is the list/array
All you have to do is : converting the items to appropriate type
var list = JObject.Parse(json)["grades"].Select(x => (int)x).ToArray();
You can also declare a class
public class RootObject
{
public string course { get; set; }
public List<int> grades { get; set; }
}
and deserialize whole object as
var myobj = JsonConvert.DeserializeObject<RootObject>(json);
var grade = myobj.grades[0];
I would typically define a class with the relevant properties and simply convert the object.
public class CourseReport
{
public string Course { get; set; }
public ICollection<int> Grades { get; set; }
}
// Reads the JSON file into a single string
string json = File.ReadAllText(jfile);
Console.WriteLine(json);
// Parsing the information to a format json.net can work with
var courseReport = JsonConvert.DeserializeObject<CourseReport>(json);
foreach (var grade in courseReport.Grades)
{
Console.WriteLine(grade);
}

Read specific value from JSON in C#

So I have a JSON string where I just want to read a specific value. How do I just pick "Read me please!" from string below?
var readString = /*Read me please!*/
JSON string:
"{\"aString\":\"Read me please!\"}"
For better understanding, how do I do the same here? (just "Read me please!"):
"{\"Result\":
{
\"aString\":\"Read me please!\",
\"anotherString\":\"Dont read me!\"
}
}"
If both alternative have different solution I would like to know both.
PS: I do not wish to save the value into object/class or so. Just temporary inside var readString.
You could write a model:
public class MyModel
{
public string AString { get; set; }
}
and then use a JSON serializer such as Json.NET:
string readString = "{\"aString\":\"Read me please!\"}";
MyModel model = JsonConvert.DeserializeObject<MyModel>(readString);
Console.WriteLine(model.AString);
If you don't want to use third party solutions you could use the built-in JavaScriptSerializer class:
string readString = "{\"aString\":\"Read me please!\"}";
MyModel model = new JavaScriptSerializer().Deserialize<MyModel>(readString);
Console.WriteLine(model.AString);
Now assuming you want to handle your second JSON string you could simply adapt your model:
public class Wrapper
{
public MyModel Result { get; set; }
}
public class MyModel
{
public string AString { get; set; }
public string AnotherString { get; set; }
}
and then deserialize to this wrapper class:
string readString = ... the JSON string in your second example ...;
Wrapper wrapper = JsonConvert.DeserializeObject<Wrapper>(readString);
Console.WriteLine(wrapper.Result.AString);
Console.WriteLine(wrapper.Result.AnotherString);
UPDATE:
And if you don't want to deserialize to a model you could directly do this:
string readString = "{\"aString\":\"Read me please!\"}";
var res = (JObject)JsonConvert.DeserializeObject(readString);
Console.WriteLine(res.Value<string>("aString"));
or with the built-in JavaScriptSerializer class:
string readString = "{\"aString\":\"Read me please!\"}";
var serializer = new JavaScriptSerializer();
var res = (IDictionary<string, object>)serializer.DeserializeObject(readString);
Console.WriteLine(res["aString"]);
var readString = JObject.Parse(str)["aString"];
Or for your second example:
var readString2 = JObject.Parse(str2)["Result"]["aString"];
Json.NET also provides a JSON reader if you don't want to deserialize the whole thing. For example:
string json = "{\"Result\": { \"aString\":\"Read me please!\", \"anotherString\":\"Dont read me!\" } }";
using (var reader = new JsonTextReader(new StringReader(json)))
{
while (reader.Read())
{
if (reader.TokenType == JsonToken.PropertyName && (string)reader.Value == "aString")
{
reader.Read();
Console.Write(reader.Value);
break;
}
}
}
Console.ReadKey();
You have to use Newtonsoft (JSON.NET) to accomplish that. Then, you can access your json property this way:
var obj = JsonConvert.DeserializeObject(yourJson);
Console.WriteLine(obj.Result.aString);
I played around with writing a generic method that can read any part of my json string. I tried a lot of the answers on this thread and it did not suit my need. So this is what I came up with. I use the following method in my service layer to read my configuration properties from the json string.
public T getValue<T>(string json,string jsonPropertyName)
{
var parsedResult= JObject.Parse(json);
return parsedResult.SelectToken(jsonPropertyName).ToObject<T>();
}
and this is how you would use it :
var result = service.getValue<List<string>>(json, "propertyName");
So you can use this to get specific properties within your json string and cast it to whatever you need it to be.

Convert Json Unicode to Utf8

I'm facing a wierd problem when converting Json Unicode(?) to UTF8
"V\u00E4xj\u00F6" should be "Växjö"
Right now it seems like I've tried everything possible, but no luck.
Any coding ninjas out there that may sit on a solution? I'm sure it's fairly easy but still can't seem to figure it out.
Thank you
As Tomalak pointed out, it can be done using the System.Web.Helpers.Json.Decode method (no external libraries, .NET Framework). You need to build a simple JSON object to fetch the decoded text:
// helper class
public class Dummy
{
public String Field { get; set; }
}
//
var value = "V\u00E4xj\u00F6";
var sb = new StringBuilder();
sb.Append("{");
sb.Append(String.Format(#"""Field"" : ""{0}""", value));
sb.Append("}");
var dummy = Json.Decode(sb.ToString());
Console.WriteLine(dummy.Field);
// it works also without helper class
var obj = Json.Decode(sb.ToString());
Console.WriteLine(obj.Field);
The output is:
Växjö
Växjö
One possibility would be to use the Json.NET library to decode the string (or maybe for the whole JSON handling?). The deserializer decodes the string automatically. My test code looks like this:
// placeholder for the example
public class Sample
{
public String Name { get; set; }
}
//
var i = #"{ ""Name"" : ""V\u00E4xj\u00F6"" }";
var jsonConverter = Newtonsoft.Json.JsonConvert.DeserializeObject(i);
Console.WriteLine(jsonConverter.ToString());
//
var sample = Newtonsoft.Json.JsonConvert.DeserializeObject<Sample>(i);
Console.WriteLine(sample.Name);
The output is:
{
"Name": "Växjö"
}
Växjö

Categories

Resources