Serializing data in to fields in JSON file [duplicate] - c#

This question already has answers here:
How to write a JSON file in C#?
(4 answers)
Closed 2 years ago.
I have a JSON File as below ,
{
"student": {
"fullName": "No Name",
"id": 0001
},
"message": "Lets see if this is displayed!"
}
I want to write some logic in my WPF application where when someone clicks the submit button after filling in the corresoonding text fields those values will be serialized into this JSON.
In the sense for example if someone enters Dwayne as the name , 2222 as the ID and "Hello" as the message I want the JSON file to look as
{
"student": {
"fullName": "Dwayne",
"id": 2222
},
"message": "Hello"
}
Here is what I have implmented thus far in my code behind
I have the StudentData.cs class
public class StudentData
{
public StudentData()
{
}
public string Name { get; set; }
public string ID { get; set; }
public string Message { get; set; }
}
and in the xaml.cs where the save is executed I get the necessary data and save it as an object
string fullName = textName.Text;
string ID = textId.Text;
string message = textMessage.Text;
StudentData stuData = new StudentData();
stuData .Name = fullName;
stuData .ID = ID;
stuData .Message = message;
Can anyone help on what I can do next ?

You should use a JSON serialisation package, I prefer Newtonsoft.
https://www.newtonsoft.com/json
You would then serialise your data into JSON and write it like this:
List<StudentData> myStudentData = new List<StudentData>();
//Add data
string json = JsonConvert.SerializeObject(myStudentData);
File.WriteAllText("c:\\path\\to\\yourfile.json", json );
This will overwrite the file you specify with the new data.
BUT:
Your data structure is not correct to achieve the JSON you wish to output. So you either need to change your expectation of the output of the data, or would need to change your classes.
With the JSON example you have then message is only shown once for the whole output. If you want this then you need to use the following classes.
public class Student
{
public string fullName { get; set; }
public int id { get; set; }
}
public class RootObject
{
public List<Student> student { get; set; }
public string message { get; set; }
}
Then you will of course have to change your creation and output of objects like this;
RootObject root = new RootObject();
root.message = "Hello";
List<StudentData> myStudentData = new List<StudentData>();
//add data to student
root.student = myStudentData;
string json = JsonConvert.SerializeObject(root);
File.WriteAllText("c:\\path\\to\\yourfile.json", json );
If you wish for the message to be per student, then you keep your current class structure and you will get the following JSON output.
{
"student": {
"fullName": "Dwayne",
"id": 2222,
"message": "Hello"
}
}

You can use Newtonsoft.json library to convert your object to json.
var student = JsonConvert.SerializeObject(StudentData);
newtonsoft.json

Related

I need to rearrange a JSON but I cant find a solution

This is the JSON im receiving, already filtered. (its coming from the google places autocomplete API)
{
"predictions": [
{
"description": "Frankfurt am Main, Deutschland",
"place_id": "ChIJxZZwR28JvUcRAMawKVBDIgQ",
},
{
"description": "Frankfurt (Oder), Deutschland",
"place_id": "ChIJb_u1AiqYB0cRwDteW0YgIQQ",
},
{
"description": "Frankfurt Hahn Flughafen (HHN), Lautzenhausen, Deutschland",
"place_id": "ChIJX3W0JgQYvkcRWBxGlm6csj0",
}
],
"status": "OK"
}
And I need to get this JSON into this format:
{
"success":true,
"message":"OK",
"data":[
{
"description":"Frankfurt Hahn Flughafen (HHN), Lautzenhausen, Deutschland",
"id":"ChIJX3W0JgQYvkcRWBxGlm6csj0"
},
{
"description":"Frankfurt Airport (FRA), Frankfurt am Main, Deutschland",
"id":"ChIJeflCVHQLvUcRMfP4IU3YdIo"
},
{
"description":"Frankfurt Marriott Hotel, Hamburger Allee, Frankfurt am Main, Deutschland",
"id":"ChIJdag3xFsJvUcRZtfKqZkzBAM"
}
]
}
I would be very g
So predictions is just renamed to "data", we change rename status to message, move it up and add a success if the http-request that happened earlier was a success or not. This does not seem so hard on the first catch, but I can't seem to find resources to transform or rearrange JSON in C#.
I would be very grateful for any tips or resources, so I can get unstuck on this probably not so difficult task. I should mention I'm fairly new to all of this.
Thank you all in advance!
First create classes thats represent your jsons
public class Prediction
{
public string description { get; set; }
public string place_id { get; set; }
}
public class InputJsonObj
{
public Prediction[] predictions { get; set; }
public string status { get; set; }
}
public class Datum
{
public string description { get; set; }
public string id { get; set; }
}
public class OutPutJsoObj
{
public bool success { get; set; }
public string message { get; set; }
public List<Datum> data { get; set; }
public OutPutJsoObj(){
data = new List<Datum>();
}
}
Then mapped objects (manually or using any of mapping libraries like AutoMapper) and create final json.
using Newtonsoft.Json;
InputJsonObj inputObj = JsonConvert.DeserializeObject<InputJsonObj >(inputJson);
OutPutJsoObj outObj = new OutPutJsoObj ();
foreach(var p in inputObj)
{
outObj.Data.Add(new Datum() { descriptions = p.descriptions , id= p.place_id }
}
string outJson = = JsonConvert.SerializeObject(outObj);
Just parse the origional json and move the data to the new json object
var origJsonObj = JObject.Parse(json);
var fixedJsonObj = new JObject {
new JProperty("success",true),
new JProperty("message",origJsonObj["status"]),
new JProperty("data",origJsonObj["predictions"])
};
it is not clear from your question what should be a success value, but I guess maybe you need this line too
if (fixedJsonObj["message"].ToString() != "OK") fixedJsonObj["success"] = false;
if you just need a fixed json
json = fixedJsonObj.ToString();
or you can create c# class (Data for example) and deserilize
Data result= fixedJsonObj.ToObject<Data>();
I like the answer from #Serge but if you're looking for a strongly typed approach we can model the input and output structure as the same set of classes and the output structure is similar, with the same relationships but only different or additional names this try this:
The process used here is described in this post but effectively we create write-only properties that will receive the data during the deserialization process and will format it into the properties that are expected in the output.
public class ResponseWrapper
{
[JsonProperty("success")]
public bool Success { get;set; }
[JsonProperty("message")]
public string Message { get;set; }
[Obsolete("This field should not be used anymore, please use Message instead")]
public string Status
{
get { return null; }
set
{
Message = value;
Success = value.Equals("OK", StringComparison.OrdinalIgnoreCase);
}
}
[JsonProperty("data")]
public Prediction[] Data { get;set; }
[Obsolete("This field should not be used anymore, please use Data instead")]
public Prediction[] Predictions
{
get { return null; }
set { Data = value; }
}
}
public class Prediction
{
public string description { get; set; }
public string place_id { get; set; }
}
Then you can deserialize and re-serialize with this code:
using Newtonsoft.Json;
...
var input = JsonConvert.DeserializeObject<ResponseWrapper>(input);
var output = JsonConvert.SerializeObject(objs, new JsonSerializerSettings
{
Formatting = Newtonsoft.Json.Formatting.Indented,
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore
});
This is a fiddle you can test with: https://dotnetfiddle.net/DsI5Yc
And the output:
{
"success": true,
"message": "OK",
"data": [
{
"description": "Frankfurt am Main, Deutschland",
"place_id": "ChIJxZZwR28JvUcRAMawKVBDIgQ"
},
{
"description": "Frankfurt (Oder), Deutschland",
"place_id": "ChIJb_u1AiqYB0cRwDteW0YgIQQ"
},
{
"description": "Frankfurt Hahn Flughafen (HHN), Lautzenhausen, Deutschland",
"place_id": "ChIJX3W0JgQYvkcRWBxGlm6csj0"
}
]
}
If you were going to go to the trouble of writing a converter for the deserialization then I find this solution is a bit simpler. I tend to use this type of solution when exposing additional properties to allow legacy data to map into a the current code base.
keeps the mapping and logic contained within the class
tells developers still writing code against the deprecated structures about the change
You can also augment this and implement a global converter to omit obsolete properties which would give you full backwards compatibility until you update the source to stop sending the legacy structure. This is a fiddle of such a solution: https://dotnetfiddle.net/MYXtGT
Inspired by these posts:
JSON.Net Ignore Property during deserialization
Is there a way to make JavaScriptSerializer ignore properties of a certain generic type?
Exclude property from serialization via custom attribute (json.net)
Json.NET: Conditional Property Serialization

Getting JSON data into C# strings

So I'm making an app and I need to extract data from JSON files dynamically.
Here is a snippet of the JSON file:
{
"004bb5ee-34ba-484a-924b-31412d898e7e": {
"title": "obj_survivalobject_elevatordoor_left"
},
"00284190-1484-4286-a198-b2ddef768c2e": {
"description": "Adds shock absorption and provides stability. Great for vehicles to prevent them from easily flipping over. This suspension has a lot of bounce, making it ideal for off-road vehicles.",
"title": "Off-Road Suspension 2"
},
"011c1ffd-7146-4e8d-8c18-17247d768ae2": {
"title": "obj_spaceship_wall04"
}
}
There is lots more in the file.
But I only need to get the title and the parent of that title. Eg:
Tag: "00284190-1484-4286-a198-b2ddef768c2e"
Name: "Off-Road Suspension 2"
I don't want the description and not all have one.
I will also be using JSON files that are selected by the user while the application is running.
try this
var jsonDeserialized = JsonConvert.DeserializeObject<Dictionary<string,Description>>(json);
var list = jsonDeserialized.Select(kvp => new TagName { Tag = kvp.Key,
Name=kvp.Value.title} ).ToList();
var output = JsonConvert.SerializeObject(list);
output
[{"Tag":"004bb5ee-34ba-484a-924b-31412d898e7e","Name":"obj_survivalobject_elevatordoor_left"},
{"Tag":"00284190-1484-4286-a198-b2ddef768c2e","Name":"Off-Road Suspension 2"},
{"Tag":"011c1ffd-7146-4e8d-8c18-17247d768ae2","Name":"obj_spaceship_wall04"}]
or this way
foreach (var item in list)
{
Console.WriteLine ( $"Tag : {item.Tag}, Name: {item.Name}");
}
classes
public class Description
{
public string description { get; set; }
public string title { get; set; }
}
public class TagName
{
public string Tag { get; set; }
public string Name { get; set; }
}
Try deserializing your Json file into a collection (list/dict/etc).
See here for details about Serializing and Deserializing in C#.

How to simply parse JSON string from a website to C#

so I have a problem:
The code in JSON that you see there is a response that a webpage gives me. And the thing I want to do is really simple:
I just want to parse for example the "user_id", or "class".
I tried few things on stackoverflow that I found but no one works...
{
"data": {
"user": {
"class": "user",
"user_id": "81046537",
"etp_guid": "76411082-73ab-5aaa-9242-0bb752cf97a4",
},
},
}
Thanks !
There are many ways you can extract the user_id from the json. The most common way is to use Newtonsoft.Json package.
Assuming the json is stored as a string, you can call JObject.Parse().
var data = "{'data': {'user': {'class': 'user','user_id': '81046537','etp_guid': '76411082-73ab-5aaa-9242-0bb752cf97a4'} } }";
JObject jObject = JObject.Parse(data);
var userId = jObject["data"]["user"]["user_id"];
Console.WriteLine($"User id {userId}");
If your json is stored as a n object, then call JObject jObject = new JObject(data)
A preferred way is to serialise your json using business object. Simply create classes to match the json structure. e.g:
public class Response
{
public Data Data { get; set; }
}
public class Data
{
public User User { get; set; }
}
public class User
{
public string Class { get; set; }
public string User_id { get; set; }
public string Etp_guid { get; set; }
}
Then deserialize your object. e.g:
var response = JsonConvert.DeserializeObject<Response>(data);
Console.WriteLine($"User id {response.Data.User.User_id}");

C# Json serialize different types

I'm trying to retrieve all data from a JSON file to my C# application.
But now the problem is that the field "info" in my json file is sometimes from the type string but it can also be the type object.
{
[
{
"id":"147786",
"canUpdate":true,
"canDelete":true,
"canArchive":true,
"hasChildren":false,
"info": "Test"
},
{
"id":"147786",
"canUpdate":true,
"canDelete":true,
"canArchive":true,
"hasChildren":false,
"info": [{"id"="1","messages":"true"}]
}
]
}
well my model you can see here below, when there are only strings in my json file i can retrieve the data without any exception but when there are also objects in the info field then i get the error can't convert the value.
Is there a way to fix this on an easy way?
public string id { get; set; }
public string canUpdate { get; set; }
public string info { get; set; }
As an option you can define the info as dynamic:
public dynamic info { get; set; }
Example
Consider the following json string:
string json = #"
[
{ 'P1': 'X', 'P2': 'Y' },
{ 'P1': 'X', 'P2': [
{'P11':'XX', 'P22':'YY'},
{'P11':'XX', 'P22':'YY'}]
}
]";
You can define such model to deserialize it:
public class C
{
public string P1 { get; set; }
public dynamic P2 { get; set; }
}
And deserialize it like this:
var obj = JsonConvert.DeserializeObject<C[]>(json);
Note
If the number of dynamic properties is too much then usually there is no point in creating the class and the following code will be enough:
var obj = (dynamic)JsonConvert.DeserializeObject(json);

Deserialize dynamic json into generic .NET object

What is the best way to deserialize the following JSON response into a generic object? For example I would like to access the response message and a the list of errors (and accessing the field name and error message of it).
{
"message": "The given data was invalid.",
"errors": {
"name": [
"Name is required."
],
"gender": [
"Gender is required."
],
"date_of_birth": [
"Date of birth is required."
]
}
}
Edit:
I would like to access the JSON object in a way something like this
string message = genericObject.message
foreach (error errorElement in genericObject.errors)
{
string errorField = errorElement.fieldName;
string errorDescription = errorElement.errorMessage;
}
Edit 2:
I don't know the possible error fields beforehand.
Since you mention that you do not know which "error fields" will be present, a dictionary is the best way to go.
Here's a simple example:
void Main()
{
string json = File.ReadAllText(#"d:\temp\test.json");
var response = JsonConvert.DeserializeObject<Response>(json);
response.Dump();
}
public class Response
{
public string Message { get; set; }
public Dictionary<string, List<string>> Errors { get; }
= new Dictionary<string, List<string>>();
}
When executing this in LINQPad, I get this output:
You can even add your own code from your question:
string json = File.ReadAllText(#"d:\temp\test.json");
var genericObject = JsonConvert.DeserializeObject<Response>(json);
string message = genericObject.Message;
foreach (var errorElement in genericObject.Errors) // see note about var below
{
string errorField = errorElement.Key;
string errorDescription = errorElement.Value.FirstOrDefault(); // see below
}
Note 1: The result of iterating a dictionary is a KeyValuePair<TKey, TValue>, in this case it would be a KeyValuePair<string, List<string>>.
Note 2: You've shown JSON having an array for each field, so errorElement.errorMessage isn't going to work properly since you may have multiple error messages.
You can nest some loops, however, to process them all:
string message = genericObject.Message;
foreach (var errorElement in genericObject.Errors) // see note about var below
{
string errorField = errorElement.Key;
foreach (string errorDescription in errorElement.Value)
{
// process errorField + errorDescription here
}
}
There are many ways to do this.
The System.Web.Helpers assembly contains the Json class which you can do:
dynamic decodedObject = Json.Decode(json);
Another way would be to use the Newtonsoft.Json nuget package:
var deserializedObject = JsonConvert.DeserializeObject<dynamic>(json);
If you are willing to use Newtonsoft.Json you can use:
var json = JsonConvert.DeserializeObject<dynamic>(originalJson);
you would have to create the following classes:
RootObject.cs containing the following properties:
public class RootObject
{
[JsonProperty("message")]
public string Message { get; set; }
[JsonProperty("errors")]
public Errors Errors { get; set; }
}
Errors.cs, containing the following properties:
public class Errors
{
[JsonProperty("name")]
public string[] Name { get; set; }
[JsonProperty("gender")]
public string[] Gender { get; set; }
[JsonProperty("date_of_birth")]
public string[] DateOfBirth { get; set; }
}
And then you read the whole thing like this:
var inputObj = JsonConvert.DeserializeObject<RootObject>(json);
Where inputObj will be of type RootObject and json is the JSON you are receiving.
If you have implemented this correctly, use it like this:
var message = inputObj.Message;
var nameErrors = inputObj.Errors;
var firstNameError = inputObj.Errors.Name[0];
Here is a visual:
Showing the whole object, filled with the properties:
The "main" error:
If you have any questions feel free to ask.

Categories

Resources