Portable Object Format (POF) serialization in .NET - c#

I have a class called MyClass and pof configuration for this type (my-pof-config.xml).
I need to serialize an instance of MyType and then send it via JMS.
In Coherence Java API, there is ExternalizableHelper.toByteArray/fromByteArray. How can I do POF (Portable Object Format) serialization and deserialization in C#?
Thank you.

In .Net you have Tangosol.Util.SerializationHelper which does the same as Java's ExternalizableHelper; something like this...
serialize:
ConfigrablePofContext serializer = new ConfigurablePofContext("...config file name...");
Binary binary = SerializationHelper.ToBinary(objectToSerialize, serializer);
byte[] bytes = binary.ToByteArray();
deserialize
ConfigrablePofContext serializer = new ConfigurablePofContext("...config file name...");
Binary binary = new Binary(byteArray);
Object deserializedValue = SerializationHelper.FromBinary(binary, serializer);

Related

Error while deserializing the JSON of float array with Newtonsoft.Json in C# console app

I'm using Newtonsoft.Json library and i can't acomplish a rather simple task:
Serialize an array of floats and then deserialize the same file.
My console aplication looks like this:
var x_train = new float[3];
x_train[0] = 0.23f;
x_train[1] = 11.23f;
x_train[2] = 22.22f;
string output = JsonConvert.SerializeObject(x_train);
JsonSerializer serializer = new JsonSerializer();
using (StreamWriter sw = new StreamWriter(_pathToSerializedObjects + "\\x_train.json"))
using (JsonWriter writer = new JsonTextWriter(sw))
{
serializer.Serialize(writer, output);
}
//The file is serialized correctly, now the problem is this block of code:
// deserialize JSON directly from a file
using (StreamReader file = File.OpenText(_pathToSerializedObjects + "\\x_train.json"))
{
JsonSerializer serializer2 = new JsonSerializer();
var dx = (float[])serializer.Deserialize(file, typeof(float[]));
Console.WriteLine(dx[0]);
Console.WriteLine(dx[1]);
Console.WriteLine(dx[2]);
}
The line :
"var dx = (float[])serializer.Deserialize(file, typeof(float[]));"
Throws:
Newtonsoft.Json.JsonSerializationException: 'Error converting value "[0.23,11.23,22.22]" to type 'System.Single[]'. Path '', line 1, position 20.'
I believe that i'm missusing the Newtonsoft.Json library but i can't find examples
of serializing primitives.
Environment:
.net Core 3.1 (Console app)
Newtonsoft.Json 12.0.3
Thanks in advance.
You are serializing twice. output contains serialized array and you are serializing that string to a file. You don't need JSON serializer to write text that already represents JSON value. You can use File.WriteAllText for that.

.net property won't deserialize from json to .net object [duplicate]

I searched through similar questions and couldn't find anything that quite matched what i was looking for.
New to C# so bear with me please.
I have some json files that i am deserializing. I want the files to deserialize to objects of the correct type, without having to define the type before hand. Here's my code:
public class loadJson
{
//path of the file location
public void readJson(string path)
{
//array of files at the path location. right now just reading one file
FileInfo[] files = new DirectoryInfo(path).GetFiles("seleniumExample.json").ToArray();
foreach (FileInfo fi in files)
{
dynamic b1 = null;
using (StreamReader file = new StreamReader(fi.FullName))
{
string fileText = file.ReadToEnd();
//Console.WriteLine(fileText);
try
{
b1 = Newtonsoft.Json.JsonConvert.DeserializeObject(fileText);
}
catch(Exception e)
{
Console.WriteLine("ERROR!!!! " + e.ToString());
}
file.Close();
}
}
}
}
I have a bunch of object types that I will be feeding into my program through json files.
I don't want to have to explicitly call b1 a Bid, or a Client, or any other specific predefined class. If I do explicitly call b1 a Bid, it loads all the info just fine and fills out the correct instance variables.
But when I use "dynamic", or general "object", it can't figure it out and just initializes to an "object".
Is there a way to perform generic deserialization and have it create an object of the correct class based on the fields defined in the json file?
Thanks in advance for the help, and i apologize if my question is incredibly unclear. If so, please just let me know how I can help clear up any ambiguity. Thanks again.
Json.NET has the ability to record the .Net object type of polymorphic types during serialization, by using the setting TypeNameHandling = TypeNameHandling.Auto. When the setting is enabled the .Net type of polymorphic objects will appear as a synthetic property called "$type", for instance:
"$type": "Newtonsoft.Json.Samples.Stockholder, Newtonsoft.Json.Tests"
However, the "$type" property is never emitted for the root object if you call the conventional methods JsonConvert.SerializeObject(Object) or JsonSerializer.Serialize(TextWriter, Object). Instead, you must use one of the serialization methods that accepts an "expected" root type, for instance SerializeObject(Object, Type, JsonSerializerSettings) or JsonSerializer.Serialize(TextWriter, Object, Type). Passing typeof(object) as the expected type guarantees the type property will appear:
var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto };
var json = JsonConvert.SerializeObject(rootObject, typeof(object), settings);
If you create your JSON files using this setting, the JSON itself will remember the type of object serialized. This type will be used by Json.NET during deserialization, as long as you use set TypeNameHandling to something other than TypeNameHandling.None. e.g.:
var settings = new Newtonsoft.Json.JsonSerializerSettings { TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto };
b1 = Newtonsoft.Json.JsonConvert.DeserializeObject(fileText, settings);
Working sample .Net fiddle here.
Caveats: this way of storing .Net types in JSON is nonstandard. Other serializers such as DataContractJsonSerializer do not process type information in this format.
Note also this caution from the Newtonsoft docs:
TypeNameHandling should be used with caution when your application deserializes JSON from an external source. Incoming types should be validated with a custom SerializationBinder when deserializing with a value other than None.
For a discussion of why this may be necessary, see TypeNameHandling caution in Newtonsoft Json, How to configure Json.NET to create a vulnerable web API, and Alvaro Muñoz & Oleksandr Mirosh's blackhat paper https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf.
Deserialize your JSON into the most basic form:
Dictionary<string, object> theData= new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(jsonString);
string baseItemName = (string)theData["baseItem"];
Dictionary<string, object> someNode= (Dictionary<string, object>)theData["something"];
string anything = (string)someNode["anything"];
string nothing = (string)someNode["nothing"];
The call to Deserialize() creates a tree of Dictionary<string, object> that you can traverse at will.

How to deserialize JSON to objects of the correct type, without having to define the type before hand?

I searched through similar questions and couldn't find anything that quite matched what i was looking for.
New to C# so bear with me please.
I have some json files that i am deserializing. I want the files to deserialize to objects of the correct type, without having to define the type before hand. Here's my code:
public class loadJson
{
//path of the file location
public void readJson(string path)
{
//array of files at the path location. right now just reading one file
FileInfo[] files = new DirectoryInfo(path).GetFiles("seleniumExample.json").ToArray();
foreach (FileInfo fi in files)
{
dynamic b1 = null;
using (StreamReader file = new StreamReader(fi.FullName))
{
string fileText = file.ReadToEnd();
//Console.WriteLine(fileText);
try
{
b1 = Newtonsoft.Json.JsonConvert.DeserializeObject(fileText);
}
catch(Exception e)
{
Console.WriteLine("ERROR!!!! " + e.ToString());
}
file.Close();
}
}
}
}
I have a bunch of object types that I will be feeding into my program through json files.
I don't want to have to explicitly call b1 a Bid, or a Client, or any other specific predefined class. If I do explicitly call b1 a Bid, it loads all the info just fine and fills out the correct instance variables.
But when I use "dynamic", or general "object", it can't figure it out and just initializes to an "object".
Is there a way to perform generic deserialization and have it create an object of the correct class based on the fields defined in the json file?
Thanks in advance for the help, and i apologize if my question is incredibly unclear. If so, please just let me know how I can help clear up any ambiguity. Thanks again.
Json.NET has the ability to record the .Net object type of polymorphic types during serialization, by using the setting TypeNameHandling = TypeNameHandling.Auto. When the setting is enabled the .Net type of polymorphic objects will appear as a synthetic property called "$type", for instance:
"$type": "Newtonsoft.Json.Samples.Stockholder, Newtonsoft.Json.Tests"
However, the "$type" property is never emitted for the root object if you call the conventional methods JsonConvert.SerializeObject(Object) or JsonSerializer.Serialize(TextWriter, Object). Instead, you must use one of the serialization methods that accepts an "expected" root type, for instance SerializeObject(Object, Type, JsonSerializerSettings) or JsonSerializer.Serialize(TextWriter, Object, Type). Passing typeof(object) as the expected type guarantees the type property will appear:
var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto };
var json = JsonConvert.SerializeObject(rootObject, typeof(object), settings);
If you create your JSON files using this setting, the JSON itself will remember the type of object serialized. This type will be used by Json.NET during deserialization, as long as you use set TypeNameHandling to something other than TypeNameHandling.None. e.g.:
var settings = new Newtonsoft.Json.JsonSerializerSettings { TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto };
b1 = Newtonsoft.Json.JsonConvert.DeserializeObject(fileText, settings);
Working sample .Net fiddle here.
Caveats: this way of storing .Net types in JSON is nonstandard. Other serializers such as DataContractJsonSerializer do not process type information in this format.
Note also this caution from the Newtonsoft docs:
TypeNameHandling should be used with caution when your application deserializes JSON from an external source. Incoming types should be validated with a custom SerializationBinder when deserializing with a value other than None.
For a discussion of why this may be necessary, see TypeNameHandling caution in Newtonsoft Json, How to configure Json.NET to create a vulnerable web API, and Alvaro Muñoz & Oleksandr Mirosh's blackhat paper https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf.
Deserialize your JSON into the most basic form:
Dictionary<string, object> theData= new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(jsonString);
string baseItemName = (string)theData["baseItem"];
Dictionary<string, object> someNode= (Dictionary<string, object>)theData["something"];
string anything = (string)someNode["anything"];
string nothing = (string)someNode["nothing"];
The call to Deserialize() creates a tree of Dictionary<string, object> that you can traverse at will.

How to handle JSON in C#?

Is there an easy/elegant parser for dealing with JSON in C#? How about actually serializing/deserializing into C# objects?
JSON.Net is a pretty good library
var jss = new JavaScriptSerializer();
var data = jss.Deserialize<dynamic>(jsonString);
Don't forget to reference "System.Web.Extensions"
See
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx
Basically you can use the 'data contract' model (that's often used for WCF XML serialization) for JSON as well. It's pretty quick and easy to use standalone for little tasks, I have found.
Also check out this sample:
http://msdn.microsoft.com/en-us/library/bb943471.aspx
There's the DataContractJsonSerializer class.
Deserialize:
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(MyObject));
Stream s = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(json_string));
MyObject obj = ser.ReadObject(s) as MyObject;
Serialize:
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(MyObject));
Stream s = new MemoryStream();
MyObject obj = new MyObject { .. set properties .. };
ser.WriteObject(s, obj);
s.Seek( SeekOrigin.Begin );
var reader = new StreamReader(s);
string json_string = reader.ReadToEnd();
DataContractJsonSerializer for serializing to/from objects.
In Silverlight 3, there's System.Json (http://msdn.microsoft.com/en-us/library/system.json(VS.95).aspx), very handy.

How do I serialize a C# anonymous type to a JSON string?

I'm attempting to use the following code to serialize an anonymous type to JSON:
var serializer = new DataContractJsonSerializer(thing.GetType());
var ms = new MemoryStream();
serializer.WriteObject(ms, thing);
var json = Encoding.Default.GetString(ms.ToArray());
However, I get the following exception when this is executed:
Type
'<>f__AnonymousType1`3[System.Int32,System.Int32,System.Object[]]'
cannot be serialized. Consider marking
it with the DataContractAttribute
attribute, and marking all of its
members you want serialized with the
DataMemberAttribute attribute. See
the Microsoft .NET Framework
documentation for other supported
types.
I can't apply attributes to an anonymous type (as far as I know). Is there another way to do this serialization or am I missing something?
Try the JavaScriptSerializer instead of the DataContractJsonSerializer
JavaScriptSerializer serializer = new JavaScriptSerializer();
var output = serializer.Serialize(your_anon_object);
As others have mentioned, Newtonsoft JSON.NET is a good option. Here is a specific example for simple JSON serialization:
return JsonConvert.SerializeObject(
new
{
DataElement1,
SomethingElse
});
I have found it to be a very flexible, versatile library.
You can try my ServiceStack JsonSerializer it's the fastest .NET JSON serializer at the moment. It supports serializing DataContract's, Any POCO Type, Interfaces, Late-bound objects including anonymous types, etc.
Basic Example
var customer = new Customer { Name="Joe Bloggs", Age=31 };
var json = customer.ToJson();
var fromJson = json.FromJson<Customer>();
Note: Only use Microsofts JavaScriptSerializer if performance is not important to you as I've had to leave it out of my benchmarks since its up to 40x-100x slower than the other JSON serializers.
For those checking this around the year 2020:
Microsoft's System.Text.Json namespace is the new king in town. In terms of performance, it is the best as far as I can tell:
var model = new Model
{
Name = "Test Name",
Age = 5
};
string json = JsonSerializer.Serialize(model);
As some others have mentioned, NewtonSoft.Json is a very nice library as well.
The fastest way I found was this:
var obj = new {Id = thing.Id, Name = thing.Name, Age = 30};
JavaScriptSerializer serializer = new JavaScriptSerializer();
string json = serializer.Serialize(obj);
Namespace: System.Web.Script.Serialization.JavaScriptSerializer
Please note this is from 2008. Today I would argue that the serializer should be built in and that you can probably use swagger + attributes to inform consumers about your endpoint and return data.
Iwould argue that you shouldn't be serializing an anonymous type. I know the temptation here; you want to quickly generate some throw-away types that are just going to be used in a loosely type environment aka Javascript in the browser. Still, I would create an actual type and decorate it as Serializable. Then you can strongly type your web methods. While this doesn't matter one iota for Javascript, it does add some self-documentation to the method. Any reasonably experienced programmer will be able to look at the function signature and say, "Oh, this is type Foo! I know how that should look in JSON."
Having said that, you might try JSON.Net to do the serialization. I have no idea if it will work
You could use Newtonsoft.Json.
var warningJSON = JsonConvert.SerializeObject(new {
warningMessage = "You have been warned..."
});
A faster alternative with Microsofts' new library on System.Text.Json
var warningJSON = JsonSerializer.Serialize(new {
warningMessage = "You have been warned..."
});
Assuming you are using this for a web service, you can just apply the following attribute to the class:
[System.Web.Script.Services.ScriptService]
Then the following attribute to each method that should return Json:
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
And set the return type for the methods to be "object"
public static class JsonSerializer
{
public static string Serialize<T>(this T data)
{
try
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
var stream = new MemoryStream();
serializer.WriteObject(stream, data);
string jsonData = Encoding.UTF8.GetString(stream.ToArray(), 0, (int)stream.Length);
stream.Close();
return jsonData;
}
catch
{
return "";
}
}
public static T Deserialize<T>(this string jsonData)
{
try
{
DataContractJsonSerializer slzr = new DataContractJsonSerializer(typeof(T));
var stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonData));
T data = (T)slzr.ReadObject(stream);
stream.Close();
return data;
}
catch
{
return default(T);
}
}
}

Categories