I have classes like these:
class MyDate
{
int year, month, day;
}
class Lad
{
string firstName;
string lastName;
MyDate dateOfBirth;
}
And I would like to turn a Lad object into a JSON string like this:
{
"firstName":"Markoff",
"lastName":"Chaney",
"dateOfBirth":
{
"year":"1901",
"month":"4",
"day":"30"
}
}
(Without the formatting). I found this link, but it uses a namespace that's not in .NET 4. I also heard about JSON.NET, but their site seems to be down at the moment, and I'm not keen on using external DLL files.
Are there other options besides manually creating a JSON string writer?
Since we all love one-liners
... this one depends on the Newtonsoft NuGet package, which is popular and better than the default serializer.
Newtonsoft.Json.JsonConvert.SerializeObject(new {foo = "bar"})
Documentation: Serializing and Deserializing JSON
Please Note
Microsoft recommends that you DO NOT USE JavaScriptSerializer
See the header of the documentation page:
For .NET Framework 4.7.2 and later versions, use the APIs in the System.Text.Json namespace for serialization and deserialization. For earlier versions of .NET Framework, use Newtonsoft.Json.
Original answer:
You could use the JavaScriptSerializer class (add reference to System.Web.Extensions):
using System.Web.Script.Serialization;
var json = new JavaScriptSerializer().Serialize(obj);
A full example:
using System;
using System.Web.Script.Serialization;
public class MyDate
{
public int year;
public int month;
public int day;
}
public class Lad
{
public string firstName;
public string lastName;
public MyDate dateOfBirth;
}
class Program
{
static void Main()
{
var obj = new Lad
{
firstName = "Markoff",
lastName = "Chaney",
dateOfBirth = new MyDate
{
year = 1901,
month = 4,
day = 30
}
};
var json = new JavaScriptSerializer().Serialize(obj);
Console.WriteLine(json);
}
}
Use Json.Net library, you can download it from Nuget Packet Manager.
Serializing to Json String:
var obj = new Lad
{
firstName = "Markoff",
lastName = "Chaney",
dateOfBirth = new MyDate
{
year = 1901,
month = 4,
day = 30
}
};
var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
Deserializing to Object:
var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<Lad>(jsonString );
Use the DataContractJsonSerializer class: MSDN1, MSDN2.
My example: HERE.
It can also safely deserialize objects from a JSON string, unlike JavaScriptSerializer. But personally I still prefer Json.NET.
A new JSON serializer is available in the System.Text.Json namespace. It's included in the .NET Core 3.0 shared framework and is in a NuGet package for projects that target .NET Standard or .NET Framework or .NET Core 2.x.
Example code:
using System;
using System.Text.Json;
public class MyDate
{
public int year { get; set; }
public int month { get; set; }
public int day { get; set; }
}
public class Lad
{
public string FirstName { get; set; }
public string LastName { get; set; }
public MyDate DateOfBirth { get; set; }
}
class Program
{
static void Main()
{
var lad = new Lad
{
FirstName = "Markoff",
LastName = "Chaney",
DateOfBirth = new MyDate
{
year = 1901,
month = 4,
day = 30
}
};
var json = JsonSerializer.Serialize(lad);
Console.WriteLine(json);
}
}
In this example the classes to be serialized have properties rather than fields; the System.Text.Json serializer currently doesn't serialize fields.
Documentation:
System.Text.Json overview
How to use System.Text.Json
You can achieve this by using Newtonsoft.json. Install Newtonsoft.json from NuGet. And then:
using Newtonsoft.Json;
var jsonString = JsonConvert.SerializeObject(obj);
Wooou! Really better using a JSON framework :)
Here is my example using Json.NET (http://james.newtonking.com/json):
using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
using System.IO;
namespace com.blogspot.jeanjmichel.jsontest.model
{
public class Contact
{
private Int64 id;
private String name;
List<Address> addresses;
public Int64 Id
{
set { this.id = value; }
get { return this.id; }
}
public String Name
{
set { this.name = value; }
get { return this.name; }
}
public List<Address> Addresses
{
set { this.addresses = value; }
get { return this.addresses; }
}
public String ToJSONRepresentation()
{
StringBuilder sb = new StringBuilder();
JsonWriter jw = new JsonTextWriter(new StringWriter(sb));
jw.Formatting = Formatting.Indented;
jw.WriteStartObject();
jw.WritePropertyName("id");
jw.WriteValue(this.Id);
jw.WritePropertyName("name");
jw.WriteValue(this.Name);
jw.WritePropertyName("addresses");
jw.WriteStartArray();
int i;
i = 0;
for (i = 0; i < addresses.Count; i++)
{
jw.WriteStartObject();
jw.WritePropertyName("id");
jw.WriteValue(addresses[i].Id);
jw.WritePropertyName("streetAddress");
jw.WriteValue(addresses[i].StreetAddress);
jw.WritePropertyName("complement");
jw.WriteValue(addresses[i].Complement);
jw.WritePropertyName("city");
jw.WriteValue(addresses[i].City);
jw.WritePropertyName("province");
jw.WriteValue(addresses[i].Province);
jw.WritePropertyName("country");
jw.WriteValue(addresses[i].Country);
jw.WritePropertyName("postalCode");
jw.WriteValue(addresses[i].PostalCode);
jw.WriteEndObject();
}
jw.WriteEndArray();
jw.WriteEndObject();
return sb.ToString();
}
public Contact()
{
}
public Contact(Int64 id, String personName, List<Address> addresses)
{
this.id = id;
this.name = personName;
this.addresses = addresses;
}
public Contact(String JSONRepresentation)
{
//To do
}
}
}
The test:
using System;
using System.Collections.Generic;
using com.blogspot.jeanjmichel.jsontest.model;
namespace com.blogspot.jeanjmichel.jsontest.main
{
public class Program
{
static void Main(string[] args)
{
List<Address> addresses = new List<Address>();
addresses.Add(new Address(1, "Rua Dr. Fernandes Coelho, 85", "15º andar", "São Paulo", "São Paulo", "Brazil", "05423040"));
addresses.Add(new Address(2, "Avenida Senador Teotônio Vilela, 241", null, "São Paulo", "São Paulo", "Brazil", null));
Contact contact = new Contact(1, "Ayrton Senna", addresses);
Console.WriteLine(contact.ToJSONRepresentation());
Console.ReadKey();
}
}
}
The result:
{
"id": 1,
"name": "Ayrton Senna",
"addresses": [
{
"id": 1,
"streetAddress": "Rua Dr. Fernandes Coelho, 85",
"complement": "15º andar",
"city": "São Paulo",
"province": "São Paulo",
"country": "Brazil",
"postalCode": "05423040"
},
{
"id": 2,
"streetAddress": "Avenida Senador Teotônio Vilela, 241",
"complement": null,
"city": "São Paulo",
"province": "São Paulo",
"country": "Brazil",
"postalCode": null
}
]
}
Now I will implement the constructor method that will receives a JSON string and populates the class' fields.
If they are not very big, what's probably your case export it as JSON.
Also this makes it portable among all platforms.
using Newtonsoft.Json;
[TestMethod]
public void ExportJson()
{
double[,] b = new double[,]
{
{ 110, 120, 130, 140, 150 },
{1110, 1120, 1130, 1140, 1150},
{1000, 1, 5, 9, 1000},
{1110, 2, 6, 10, 1110},
{1220, 3, 7, 11, 1220},
{1330, 4, 8, 12, 1330}
};
string jsonStr = JsonConvert.SerializeObject(b);
Console.WriteLine(jsonStr);
string path = "X:\\Programming\\workspaceEclipse\\PyTutorials\\src\\tensorflow_tutorials\\export.txt";
File.WriteAllText(path, jsonStr);
}
If you are in an ASP.NET MVC web controller it's as simple as:
string ladAsJson = Json(Lad);
Can't believe no one has mentioned this.
I would vote for ServiceStack's JSON Serializer:
using ServiceStack;
string jsonString = new { FirstName = "James" }.ToJson();
It is also the fastest JSON serializer available for .NET:
http://www.servicestack.net/benchmarks/
Another solution using built-in System.Text.Json (.NET Core 3.0+) where an object is self-sufficient and doesn't expose all possible fields:
A passing test:
using NUnit.Framework;
namespace Intech.UnitTests
{
public class UserTests
{
[Test]
public void ConvertsItselfToJson()
{
var userName = "John";
var user = new User(userName);
var actual = user.ToJson();
Assert.AreEqual($"{{\"Name\":\"{userName}\"}}", actual);
}
}
}
An implementation:
using System.Text.Json;
using System.Collections.Generic;
namespace Intech
{
public class User
{
private readonly string name;
public User(string name)
{
this.name = name;
}
public string ToJson()
{
var params = new Dictionary<string, string>{{"Name", name}};
return JsonSerializer.Serialize(params);
}
}
}
In your Lad model class, add an override to the ToString() method that returns a JSON string version of your Lad object.
Note: you will need to import System.Text.Json;
using System.Text.Json;
class MyDate
{
int year, month, day;
}
class Lad
{
public string firstName { get; set; };
public string lastName { get; set; };
public MyDate dateOfBirth { get; set; };
public override string ToString() => JsonSerializer.Serialize<Lad>(this);
}
It is as easy as this (it works for dynamic objects as well (type object)):
string json = new
System.Web.Script.Serialization.JavaScriptSerializer().Serialize(MYOBJECT);
Here is another solution using Cinchoo ETL - an open source library
public class MyDate
{
public int year { get; set; }
public int month { get; set; }
public int day { get; set; }
}
public class Lad
{
public string firstName { get; set; }
public string lastName { get; set; }
public MyDate dateOfBirth { get; set; }
}
static void ToJsonString()
{
var obj = new Lad
{
firstName = "Tom",
lastName = "Smith",
dateOfBirth = new MyDate
{
year = 1901,
month = 4,
day = 30
}
};
var json = ChoJSONWriter.Serialize<Lad>(obj);
Console.WriteLine(json);
}
Output:
{
"firstName": "Tom",
"lastName": "Smith",
"dateOfBirth": {
"year": 1901,
"month": 4,
"day": 30
}
}
Disclaimer: I'm the author of this library.
Serializer
public static void WriteToJsonFile<T>(string filePath, T objectToWrite, bool append = false) where T : new()
{
var contentsToWriteToFile = JsonConvert.SerializeObject(objectToWrite, new JsonSerializerSettings
{
Formatting = Formatting.Indented,
});
using (var writer = new StreamWriter(filePath, append))
{
writer.Write(contentsToWriteToFile);
}
}
Object
namespace MyConfig
{
public class AppConfigurationSettings
{
public AppConfigurationSettings()
{
/* initialize the object if you want to output a new document
* for use as a template or default settings possibly when
* an app is started.
*/
if (AppSettings == null) { AppSettings=new AppSettings();}
}
public AppSettings AppSettings { get; set; }
}
public class AppSettings
{
public bool DebugMode { get; set; } = false;
}
}
Implementation
var jsonObject = new AppConfigurationSettings();
WriteToJsonFile<AppConfigurationSettings>(file.FullName, jsonObject);
Output
{
"AppSettings": {
"DebugMode": false
}
}
I am trying to do an exercise about write and read data to file. The program have room, customer and hotel class and after i create object and give value for it, i try to serilize and write it to file in XML format but i encounter the exception above. I have try an example about this and it is running normally. Am i missing some declaration somewhere?
This is my XMLSerializer.cs:
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace Assignment7
{
class XMLSerializer
{
string filePath;
public XMLSerializer(string filePath)
{
this.filePath = filePath;
}
//This generic method serializes (writes) the object of generic data type to the file.
public string WriteXML<T>(T type)
{
StringBuilder feedback = new StringBuilder();
feedback.AppendLine("Provided data is invalid!");
if (type == null)
return feedback.ToString();
//Here we define an XmlSerializer object
XmlSerializer xmlSerializer = new XmlSerializer(type.GetType());
//Here we define an XmlWriter object and define settings for it.
XmlWriter xmlWriter = XmlWriter.Create(filePath,
new XmlWriterSettings()
{
OmitXmlDeclaration = true,
//ConformanceLevel specifies the level of conformance
//(document, fragment, or automatic detection).
//The default is Document.
ConformanceLevel = ConformanceLevel.Auto,
Indent = true
});
//Here we serialize data to the file
xmlSerializer.Serialize(xmlWriter, type);
//Here we clos ehe stream
xmlWriter.Close();
FileInfo fileInfo = new FileInfo(filePath);
if (fileInfo.Exists)
{
feedback.Clear();
feedback.AppendLine(fileInfo.FullName + " exists? " + fileInfo.Exists + ". Current length: " + fileInfo.Length);
}
return feedback.ToString();
}
}
}
This is my Program.cs:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Asignment7
{
class Program
{
static void Main(string[] args)
{
string filePath = #"D:\Study\Windows\hotel.xml";
Room tulip = new Room("A01", "South", "Single", 20, "Small room suitable for 1 person.");
Room lily = new Room("A11", "North", "Double", 40, "Big room for couple.");
Room blossom = new Room("B01", "East", "President", 150, "Luxury experience room.");
ArrayList rooms = new ArrayList { tulip, lily, blossom };
Customer Cus1 = new Customer("Trung", "401 Voyrinkatu", "14/02", 1);
Customer Cus2 = new Customer("Viet", "52 Handel", "14/03", 3);
Customer Cus3 = new Customer("David", "50 Palosarentie", "28/02", 2);
ArrayList customers = new ArrayList { Cus1, Cus2, Cus3 };
Hotel hotel = new Hotel("Lion Head", "18-03-1999", "Korsholm 89, Vaasa", 50, rooms, customers);
XMLSerializer xmlSerializer = new XMLSerializer(filePath);
Console.WriteLine(xmlSerializer.WriteXML<Room>(tulip));
Console.ReadLine();
}
}
}
This is my Hotel.cs:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
namespace Assignment7
{
[XmlRoot("hotel")]
class Hotel
{
[XmlElement("name")]
public string HotelName { get; set; }
[XmlElement("date")]
public string ConstructionDate { get; set; }
[XmlElement("address")]
public string Address { get; set; }
[XmlElement("staff")]
public int Staff { get; set; }
[XmlIgnore]
public ArrayList Rooms { get; set; }
[XmlIgnore]
public ArrayList Customers { get; set; }
public Hotel() { }
public Hotel(string name, string constructionDate, string address, int staff, ArrayList rooms, ArrayList customers)
{
this.HotelName = name;
this.ConstructionDate = constructionDate;
this.Address = address;
this.Staff = staff;
this.Rooms = rooms;
this.Customers = customers;
}
}
}
This is my Room.cs:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
namespace Assignment7
{
[XmlRoot("room")]
class Room
{
[XmlElement("number")]
public string RoomNumber { get; set; }
[XmlElement("area")]
public string Area { get; set; }
[XmlElement("type")]
public string Type { get; set; }
[XmlElement("price")]
public double PricePerNight { get; set; }
[XmlElement("description")]
public string Description { get; set; }
public Room() { }
public Room(string roomNumber, string area, string type, double pricePerNight, string description)
{
this.RoomNumber = roomNumber;
this.Area = area;
this.Type = type;
this.PricePerNight = pricePerNight;
this.Description = description;
}
}
}
This is my Customer.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
namespace Assignment7
{
[XmlRoot("customer")]
class Customer
{
[XmlElement("name")]
public string CustomerName
{
get; set;
}
[XmlElement("room")]
public string RoomNumber
{
get; set;
}
[XmlElement("arrival")]
public string ArrivalDate
{
get; set;
}
[XmlElement("length")]
public int LengthOfStay
{
get; set;
}
public Customer() { }
public Customer(string name, string roomNumber, string arrivalDate, int lengthOfStay)
{
this.CustomerName = name;
this.RoomNumber = roomNumber;
this.ArrivalDate = arrivalDate;
this.LengthOfStay = lengthOfStay;
}
}
}
Using an open API (im using New York Times book api) create an API Gateway endpoint that does the following:
Retrieves data from an API.
Stores the data in a database.
im able to retrieve the data and store it in a string but im have difficulties extracting that data from the string and storing it into a dynamoDb. Any help is appreciated thank you.
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Amazon.Lambda.Core;
using Newtonsoft.Json.Linq;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DocumentModel;
using Amazon.Lambda.APIGatewayEvents;
using Amazon.DynamoDBv2.Model;
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
namespace last
{
public class Result
{
public string url { get; set; }
public string publication_dt { get; set; }
public string byline { get; set; }
public string book_title { get; set; }
public string book_author { get; set; }
public string summary { get; set; }
public List<string> isbn13 { get; set; }
}
public class Root
{
public string status { get; set; }
public string copyright { get; set; }
public int num_results { get; set; }
public List<Result> results { get; set; }
}
public class Function
{
private static AmazonDynamoDBClient client1 = new AmazonDynamoDBClient();
public static readonly HttpClient client = new HttpClient();
public async Task<ExpandoObject> FunctionHandler(string input, ILambdaContext context)
{
string tblName = "last";
string url = "https://api.nytimes.com/svc/books/v3/reviews.json?title=Becoming&api-key=myKey";
string message = await client.GetStringAsync(url);
Result myDeserializedClass = JsonConvert.DeserializeObject<Result>(message);
var request = new PutItemRequest
{
TableName = tblName,
Item = new Dictionary<string, AttributeValue>()
{
{ "bookId", new AttributeValue { S = "202" }},
{ "publication_dt", new AttributeValue { S = myDeserializedClass.publication_dt.ToString() }},
{ "byline", new AttributeValue { S = myDeserializedClass.byline.ToString() }},
{ "book_title", new AttributeValue { S = myDeserializedClass.book_title.ToString()}},
{ "book_author", new AttributeValue { S = myDeserializedClass.book_author.ToString() }},
{ "summary", new AttributeValue { S = myDeserializedClass.summary.ToString() }},
{ "isbn13", new AttributeValue { S = myDeserializedClass.isbn13.ToString()}},
}
};
await client1.PutItemAsync(request);
//Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(message);
//await tblName.PutItemAsync((Document)myDeserializedClass.ToString());
return JsonConvert.DeserializeObject<ExpandoObject>(message);
}
}
}
I created a class called employees, created three employees. I then created a List<> to store the employee objects
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AutomationTest
{
public class Employees
{
public String ID { get; set; }
public String Name { get; set; }
public List<int> Salary { get; set; }
public static List<Employees> GetEmployeesSalaries()
{
List<Employees> employees = new List<Employees>();
List<int> johnsalary = new List<int> { 1100,1200,1300 };
List<int> jamessalary = new List<int> { 1400, 1450, 1500 };
List<int> timsalary = new List<int> { 1600, 1700, 17500 };
employees.Add(new Employees { ID = "N001", Name = "John", Salary = johnsalary });
employees.Add(new Employees { ID = "N002", Name = "James", Salary = jamessalary });
employees.Add(new Employees { ID = "N003", Name = "Tim", Salary = timsalary });
return employees;
}
}
}
I then created the query statement but got the project.class name on the console output as Automationtest.Employee
using System.Text;
using System.Threading.Tasks;
namespace AutomationTest
{
class Program
{
static void Main(string[] args)
{
IEnumerable<Employees> querysalary = (Employees.GetEmployeesSalaries().Where(i => i.Name.Contains("m"))).ToList<Employees>();
//IEnumerable<Employees> querysalary = from empl in Employees.GetEmployeesSalaries()
// where empl.Name.Contains("a") select empl;
//var querysalary = (from k in Employees.GetEmployeesSalaries() select k).ToString();
foreach (var ss in querysalary)
{
Console.WriteLine(ss);
}
Console.ReadLine();
}
}
}
On Console.WriteLine you are calling the .toString() method of the object wich will give you no readable form of the object. You can override it to create your own implementation. Try to add thid function this in your Employees Class
public override string ToString()
{
return $"{ID} {Name} {String.Join(", ", Salary)}";
}
For the list you have to iterate over the individual entries and put them in a string. This can be done with the String.Join method.
Working example:
public static void Main(string[] args)
{
var character = new Employee();
Console.Write(character);
}
public class Employee
{
public Employee()
{
Salary = new List<int> { 2, 3, 4 };
}
public override string ToString()
{
return $"{String.Join(", ", Salary)}";
}
public List<int> Salary { get; set; }
}
Here I have a scenario that Create xml file dynamically and it should be serialisable. xml is like:
<person>
<personaldata>
<name>gopi</name>
<lastname>ch</lastname>
</personaladata>
<Educationaladata>
<Graduation>b.tech</graduation>
<designation>Engineer</designation>
</educationaldata>
</person>
person class has name, lastname, designation, graduation and properties
I tried this
public string CreateXmlObject(Person objPerson)
{
var objXmlDocument = new XmlDocument();
var objXpath = objXmlDocument.CreateNavigator();
var objXmlSeialiser = new XmlSerializer(objPerson.GetType());
using (var xs = objXpath.AppendChild())
{
objXmlSeialiser.Serialize(xs, objPerson);
}
return objXmlDocument.OuterXml;
}
My Problem is I have to read Specific data from Xml And Update Specific data to Xml . I want to read only Personaldata when i update, update should only apply to Personaldata Not Otherdata
Try xml linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string name = "gopi";
string lastname = "ch";
string graduation = "b.tech";
string designation = "Engineer";
XElement personalData = new XElement("person", new XElement[] {
new XElement("personaldata", new XElement[] {
new XElement("name", name),
new XElement("lastname", lastname)
}),
new XElement("Educationadata", new XElement[] {
new XElement("Graduation", graduation),
new XElement("designation", designation)
})
});
}
}
}
Fisrt of all your XML is invalid, all the nodes should match their closing tags. Considering your person class looks something like this:-
public class Person
{
public string name { get; set; }
public string lastname { get; set; }
public string Graduation { get; set; }
public string designation { get; set; }
}
You can easily do it with LINQ-to-XML:-
Xdocument = XDocument.Load("XMLFilePath");
List<Person> persons = (from person in xdoc.Descendants("person")
let personaldata = person.Element("personaldata")
let Educationaladata = person.Element("Educationaladata")
select new Person
{
name = (string)personaldata.Element("name"),
lastname = (string)personaldata.Element("lastname"),
Graduation = (string)Educationaladata.Element("Graduation"),
designation = (string)Educationaladata.Element("designation")
}).ToList();
sSometing like -
var xml = XDocument.Load("xml path");
var personaldata = xml.Descendents("personaldata").FirstOrDefault();
if (data != null)
{
foreach (var t in data.Descendants())
{
t.Value = "test";
}
}