Best way to convert C# Class to JSON representation - c#

I've got c# objects that I need references to in javascript for default population. Currently I'm maintaining 2 different objects which is not that maintainable.
For example ( simplified for demo purposes ):
C#
public class Text
{
public string Name {get;set;}
}
JSON
{
'text': {
name: undefined
}
}
I know there is a number of ways to accomplish this but wondering if anyone has a recommended solution. Thanks!

I personally recommend json.NET. Getting the json of any object is as simple as;
using Newtonsoft.Json;
string json = JsonConvert.SerializeObject(new Text { Name = "test" });
There are a lot of other options but I've been using it since before there was json serilization support in .NET and I strongly prefer it over what is there now. In fact I think it's better in every way, if you want a big robust data layer I like it more and it's vastly superior for one off serilizations.

If you are using .NET 4.0 or above, you can use DataContractJsonSerializer class.

I recommend you to look at this benchmark http://theburningmonk.com/2013/09/binary-and-json-serializer-benchmarks-updated/

Related

How to convert UpdateResult from MongoDB C# Driver to JSON

Providing some contextual information: I want to integrate some technology with MongoDB using the official C# driver, but due some limitations I need to integrate it using only JSON strings. So, I'm building a simple wrapper to the native functions to call they by passing and receiving JSON as simple strings.
Example of the find method:
public string find(string json)
{
BsonDocument query = BsonDocument.Parse(json);
var list = Collection.Find(query).ToListAsync().Result;
return list.ToJson();
}
P.S.: I know the performance implications of using an async method as a synchronous one, but I have no choice.
This works pretty well, the problem is with the update/replace method:
public string updateMany(string jsonFilter, string jsonUpdate)
{
BsonDocument filter = BsonDocument.Parse(jsonFilter);
BsonDocument update = BsonDocument.Parse(jsonUpdate);
UpdateResult r = Collection.UpdateManyAsync(filter, update).Result;
return r.ToJson();
}
This returns the string: { "_t" : "Acknowledged" }, which only tells me the class of the UpdateManyAsync() result. That class expose some properties like MatchedCount and ModifiedCount that I would like to put on JSON too, but the default serializer is ignoring them by some reason (those properties are read-only, so should be ignored on deserializing, but not on serializing).
I tried to use r.ToJson<UpdateResult>(); and r.ToBsonDocument<UpdateResult>();, but got the same result.
I saw that toJson() has some overloads receiving a JsonWriterSettings, an IBsonSerializer and a BsonSerializationArgs, so maybe one of them holds some configuration about the subject, but I have no luck searching for it.
I think that I could import Json.NET DLL to see if it serializes all the properties, but I would like to solve it without another dependency.

Serialize a decimal to a human readable currency format

I am using json.net library to serialize an object which has a decimal value that represents a cost. When serializing, I want the json to look something like '$400,000' instead of '400000.0'.
Is there a way that I can accomplish this in an easy and efficient way? This object contains many other secondary objects and subsequent properties.
The application will be used locally and the specs say that the output should be in human readable format. Culture variance isn't of any importance in this context.
There's no easy way to perform this since you can't work around a fact that serializer is directly accessing your properties.
If you need a formatted JSON output I would recommend writing a helper class that wraps the class you want to expose. Unfortunately I've done this once for some XML report and really the easiest way went something like this:
class PersonXml
{
Person _person;
void PersonXml(Person person) { _person = person; }
string Age { get { return _person.Age + " years"; } }
}
This is just a simple example I wrote on the fly but the principle is always the same. Even if some advanced JSON serializer offered me ways to format my output, I'd really keep this concept out of my main objects in a separate file with separate helper classes.
Again this isn't quite the solution, in my opinion it should never come to this but if it does, this is the lesser of the evils in my experience.
Also, just note that if you reference the class in your property getters there's a danger of null reference.
As D Stanley suggested, I changed the field type to string from decimal as data in it was only being read and not used for data manipulation.

How to parse this decenturl code?

I have this code:
["ok", "Google", "google"]
That I get from decenturl.com/api-title?u=google.com. This API gets the title of a site, but it is "encoded" in the format above. What is the format of this? I tried to search for it, but without the name I can't do anything. It looks like JSON, but it isn't, I guess.
Anyway, how do I parse this in C#? Will be better if this work in framework 2.0, but if can't, I accept above frameworks. There is a built-in method for that? Or I need to do it manually?
Thanks.
It is JSON, just for an array. Assuming the URL always gives you back JSON, you could parse it like this (using Json.NET, which still supports .NET 2.0):
using System;
using Newtonsoft.Json.Linq;
class Test
{
static void Main()
{
string json = "[\"ok\", \"Google\", \"google\"]";
var array = JArray.Parse(json);
Console.WriteLine(array[0]); // For example
}
}

Is there such thing as a CSV Serializer? (similar to XmlSerializer)

I am toying around with serializing and deserializing CSV files and I am wondering if there is an existing library, similar in concept to the XmlSerializer, which can declaratively define objects and (de)serialize them to/from a file or stream. I have looked around a bit but have not found anything focused on serialization. I already have pretty solid code for parsing CSV documents per RFC 4180, but what would be really helpful is the serialization part. What I am not looking for is just a parser, advice to use String.Split(), etc.
Is there an existing project out there, or should I build one?
Bonus etiquette question: if I do end up rolling my own serializer, is it appropriate to answer this question with a link to the codeplex project?
I would highly recommend servicestack.text for this purpose. Avialable on nuget:
Install-package servicestack.text
It suports serialization to many data formats and unlike the built in XmlSerializer, you don't need to decorate all your properties with attributes. Here's an example to serialize to CSV.
using ServiceStack.Text;
...
var csv = CsvSerializer.SerializeToCsv(new[]{
new Dog () {
Bark = "Woof!",
Male = true,
Size = 10
}});
I've used this project (CsvHelper) in the past, and it works similar to the build in .NET serializer classes in the sense that you use attributes to craft the input/output.
There's really no need to roll your own, since there are tons out there. If you do end up rolling your own, feel free to post it. Most users, when answering a question with something they've written themselves (or are affiliated in some way) usually give a disclaimer saying so as a courtesy.
You should take a look into FileHelpers Library.
Some sample code from their site:
using FileHelpers;
// First declare the record class
[DelimitedRecord(",")]
public class SampleType
{
public string Field1;
public int Field2;
}
public void WriteExample()
{
FileHelperEngine engine = new FileHelperEngine(typeof(SampleType));
SampleType[] records = new SampleType[1];
records[0] = new SampleType();
records[0].Field1 = "Hello World";
records[0].Field2 = 12;
engine.WriteFile("destination.txt", records);
// Now the file contains the created record in this format:
//
// Hello World,12
}

Transferring data from C# to Java via serialization

I have a Java application for Android that will have some static data, which will be loaded at start up. This data is generated by a C# app as a bunch of classes with lists and Dictionaries, something like this:
public class DataContainer
{
public List<A> As = new List<A>();
public Dictionary<int, B> Bs = new Dictionary<int, B>();
// ...
}
public class A
{
public int IdA;
public int IdSomething;
public DateTime dt;
//...
}
public class B
{
public int IdB;
public string Name;
List<C> Cs = new List<C>();
//...
}
public class C
{
//...
}
(The DataContainer class is the root class that contains all the data to be transferred. I then have a similar class structure in the Java project into which I want the data to be imported.)
My issue is that I can't seem to find a combination of a .NET and Java tools/libraries that would be able to write and read the same format.
I've tried JSON with DataContractJsonSerializer and then loading with GSON but that doesn't work with Dictionaries/Maps (works fine with Lists but I need the dictionaries). The .NET exporter uses format like
"Bs":[{"Key":1,"Value":{...}}, ...]
while it looks like GSON uses
{key:value,key:value,...}
I've also looked at some XML but since there isn't a standard formatting all the libraries use something different by default and I really don't want to write all the writing/parsing rules by hand. Also, JSON has much less overhead compared to XML.
So, is there some pair of libraries for .NET export and Java import that can handle nested classes with Lists and Dictionaries? The things I've managed to find were either in the other direction or did just simple one class serialization.
BTW: I'm also using Tuples for Dictionary keys, but if nothing can handle that I'll just use nested Dictionaries, that is not a big deal.
EDIT: Since I can't answer my own question due to low rep here is the solution that worked for me:
So, I've tried a few more combinations and serializing using JSon.NET on the C#/.NET side and then loading using GSON on the Java side works great, except Tuples. For example, using Tuple as a key for dictionary will get serialized as:
{ "(False, 3)" : { ... }, "(True, 1)" : { ... }, ... }
So I have to use String keys in Java for now but that is not an issue. Possible solution is to write a custom class for the Tuple in both .NET and Java.
Example code:
string serializeObject = JsonConvert.SerializeObject(dataContainer, new IsoDateTimeConverter());
File.WriteAllText("test.json", serializeObject);
and Java:
InputStream is = getResources().openRawResource(R.raw.test); // open from /res/raw/test.json
Gson gson = new Gson();
InputStreamReader r = new InputStreamReader(is);
DataContainer dc = gson.fromJson(r, DataContainer.class);
Log.i("jsondebug", dc.Packers.get(0).Something);
You can have a look at Google Protocol Buffers. Protocol buffers are Google's lingua franca for data. Below is an excerpt from Protocol Buffers Developer Guide:
Protocol buffers are a flexible, efficient, automated mechanism for
serializing structured data – think XML, but smaller, faster, and
simpler. You define how you want your data to be structured once, then
you can use special generated source code to easily write and read
your structured data to and from a variety of data streams and using a
variety of languages. You can even update your data structure without
breaking deployed programs that are compiled against the "old" format.
Protocol buffers have many advantages over XML for serializing
structured data. Protocol buffers:
are simpler
are 3 to 10 times smaller
are 20 to 100 times faster
are less ambiguous
generate data access classes that are easier to use programmatically
An XML mapping would work just fine. Serialize as XML and send it over. You'll need marshallers and unmarshallers on either end.
Java has its JAXB standard for binding XML to objects. Perhaps you can manage it if you follow that standard.
I think you need to approach this from a different perspective. Think first about a JSON or XML format that will work well with both the C# and Java side. Think of that as an API or contract between the C# and Android apps. Instead of using libraries that marshall/unmarshall according to their own formats, make the code on each side read/write to the contract you defined.
Alternatively, you might want to look into using a binary format like Apache Thrift or Protocol Buffers.

Categories

Resources