Serialize Array of Vector2 with Json.NET - arrays

I am trying to use Json.NET on Unity to serialize a class.
The class Polygon contains an Array of Vector2 but i only want to serialize the x and y variables of Vector2 class, that's why I'm using the JsonConverter attribute.
Sample class:
public class Polygon
{
public int count { get; set; }
[JsonConverter(typeof(Vector2Converter[]))]
public Vector2[] points { get; set; }
}
It gives me this error at runtime:
MissingMethodException: Method not found: 'Default constructor not
found...ctor() of
JsonDotNet.Extras.CustomConverters.Vector2Converter[]
Anyone have any suggestions?

The [JsonConverter] attribute takes the type of a converter, not the type of an array of converters. If your converter is designed to handle the serialization of the entire array, then you need to specify it like this:
[JsonConverter(typeof(Vector2Converter))]
public Vector2[] points { get; set; }
If your converter is designed to serialize the individual items in the array, you need to use this syntax instead:
[JsonProperty(ItemConverterType=typeof(Vector2Converter))]
public Vector2[] points { get; set; }

Related

Hashset to string [duplicate]

I have a class defined as follows:
public class Person {
private String name;
// constructor and getter/setter omitted
}
I tried to print an instance of my class:
System.out.println(myPerson);
but I got the following output: com.foo.Person#2f92e0f4.
A similar thing happened when I tried to print an array of Person objects:
Person[] people = //...
System.out.println(people);
I got the output: [Lcom.foo.Person;#28a418fc
What does this output mean? How do I change this output so it contains the name of my person? And how do I print collections of my objects?
Note: this is intended as a canonical Q&A about this subject.
Background
All Java objects have a toString() method, which is invoked when you try to print the object.
System.out.println(myObject); // invokes myObject.toString()
This method is defined in the Object class (the superclass of all Java objects). The Object.toString() method returns a fairly ugly looking string, composed of the name of the class, an # symbol and the hashcode of the object in hexadecimal. The code for this looks like:
// Code of Object.toString()
public String toString() {
return getClass().getName() + "#" + Integer.toHexString(hashCode());
}
A result such as com.foo.MyType#2f92e0f4 can therefore be explained as:
com.foo.MyType - the name of the class, i.e. the class is MyType in the package com.foo.
# - joins the string together
2f92e0f4 the hashcode of the object.
The name of array classes look a little different, which is explained well in the Javadocs for Class.getName(). For instance, [Ljava.lang.String means:
[ - an single-dimensional array (as opposed to [[ or [[[ etc.)
L - the array contains a class or interface
java.lang.String - the type of objects in the array
Customizing the Output
To print something different when you call System.out.println(myObject), you must override the toString() method in your own class. Here's a simple example:
public class Person {
private String name;
// constructors and other methods omitted
#Override
public String toString() {
return name;
}
}
Now if we print a Person, we see their name rather than com.foo.Person#12345678.
Bear in mind that toString() is just one way for an object to be converted to a string. Typically this output should fully describe your object in a clear and concise manner. A better toString() for our Person class might be:
#Override
public String toString() {
return getClass().getSimpleName() + "[name=" + name + "]";
}
Which would print, e.g., Person[name=Henry]. That's a really useful piece of data for debugging/testing.
If you want to focus on just one aspect of your object or include a lot of jazzy formatting, you might be better to define a separate method instead, e.g. String toElegantReport() {...}.
Auto-generating the Output
Many IDEs offer support for auto-generating a toString() method, based on the fields in the class. See docs for Eclipse and IntelliJ, for example.
Several popular Java libraries offer this feature as well. Some examples include:
ToStringBuilder from Apache Commons Lang
MoreObjects.ToStringHelper from Google Guava
#ToString annotation from Project Lombok
Printing groups of objects
So you've created a nice toString() for your class. What happens if that class is placed into an array or a collection?
Arrays
If you have an array of objects, you can call Arrays.toString() to produce a simple representation of the contents of the array. For instance, consider this array of Person objects:
Person[] people = { new Person("Fred"), new Person("Mike") };
System.out.println(Arrays.toString(people));
// Prints: [Fred, Mike]
Note: this is a call to a static method called toString() in the Arrays class, which is different to what we've been discussing above.
If you have a multi-dimensional array, you can use Arrays.deepToString() to achieve the same sort of output.
Collections
Most collections will produce a pretty output based on calling .toString() on every element.
List<Person> people = new ArrayList<>();
people.add(new Person("Alice"));
people.add(new Person("Bob"));
System.out.println(people);
// Prints [Alice, Bob]
So you just need to ensure your list elements define a nice toString() as discussed above.
I think apache provides a better util class which provides a function to get the string
ReflectionToStringBuilder.toString(object)
Every class in Java has the toString() method in it by default, which is called if you pass some object of that class to System.out.println(). By default, this call returns the className#hashcode of that object.
{
SomeClass sc = new SomeClass();
// Class # followed by hashcode of object in Hexadecimal
System.out.println(sc);
}
You can override the toString method of a class to get different output. See this example
class A {
String s = "I am just a object";
#Override
public String toString()
{
return s;
}
}
class B {
public static void main(String args[])
{
A obj = new A();
System.out.println(obj);
}
}
In Eclipse,
Go to your class,
Right click->source->Generate toString();
It will override the toString() method and will print the object of that class.
I prefer to use a utility function which uses GSON to de-serialize the Java object into JSON string.
/**
* This class provides basic/common functionalities to be applied on Java Objects.
*/
public final class ObjectUtils {
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private ObjectUtils() {
throw new UnsupportedOperationException("Instantiation of this class is not permitted in case you are using reflection.");
}
/**
* This method is responsible for de-serializing the Java Object into Json String.
*
* #param object Object to be de-serialized.
* #return String
*/
public static String deserializeObjectToString(final Object object) {
return GSON.toJson(object);
}
}
In intellij you can auto generate toString method by pressing alt+inset and then selecting toString() here is an out put for a test class:
public class test {
int a;
char b;
String c;
Test2 test2;
#Override
public String toString() {
return "test{" +
"a=" + a +
", b=" + b +
", c='" + c + '\'' +
", test2=" + test2 +
'}';
}
}
As you can see, it generates a String by concatenating, several attributes of the class, for primitives it will print their values and for reference types it will use their class type (in this case to string method of Test2).
By default, every Object in Java has the toString() method which outputs the ObjectType#HashCode.
If you want more meaningfull information then you need to override the toString() method in your class.
public class Person {
private String name;
// constructor and getter/setter omitted
// overridding toString() to print name
public String toString(){
return name;
}
}
Now when you print the person object using System.out.prtinln(personObj); it will print the name of the person instead of the classname and hashcode.
In your second case when you are trying to print the array, it prints [Lcom.foo.Person;#28a418fc the Array type and it's hashcode.
If you want to print the person names, there are many ways.
You could write your own function that iterates each person and prints
void printPersonArray(Person[] persons){
for(Person person: persons){
System.out.println(person);
}
}
You could print it using Arrays.toString(). This seems the simplest to me.
System.out.println(Arrays.toString(persons));
System.out.println(Arrays.deepToString(persons)); // for nested arrays
You could print it the java 8 way (using streams and method reference).
Arrays.stream(persons).forEach(System.out::println);
There might be other ways as well. Hope this helps. :)
If you Directly print any object of Person It will the ClassName#HashCode to the Code.
in your case com.foo.Person#2f92e0f4 is getting printed . Where Person is a class to which object belongs and 2f92e0f4 is hashCode of the Object.
public class Person {
private String name;
public Person(String name){
this.name = name;
}
// getter/setter omitted
#override
public String toString(){
return name;
}
}
Now if you try to Use the object of Person then it will print the name
Class Test
{
public static void main(String... args){
Person obj = new Person("YourName");
System.out.println(obj.toString());
}
}
If you look at the Object class (Parent class of all classes in Java) the toString() method implementation is
public String toString() {
return getClass().getName() + "#" + Integer.toHexString(hashCode());
}
whenever you print any object in Java then toString() will be call. Now it's up to you if you override toString() then your method will call other Object class method call.
Using Lombok #Data annotation on class will provide getter, setter, toString and hashcode. Using Lombok is better as it handles boilerplate code.
For a "deep" toString() there is an alternative to the JSON based answers (Jackson, GSON, etc.): ReflectionToStringBuilder from the Apache Commons Lang 3 library, with RecursiveToStringStyle or MultilineRecursiveToStringStyle. Code example:
System.out.println("My object: " +
ReflectionToStringBuilder.toString(theObject, new RecursiveToStringStyle()));
Output examples:
// RecursiveToStringStyle
Person#7f54[name=Stephen,age=29,smoker=false,job=Job#43cd2[title=Manager]]
// MultilineRecursiveToStringStyle
Person#7f54[
name=Stephen,
age=29,
smoker=false,
job=Job#43cd2[
title=Manager
]
]
I managed to get this done using Jackson in Spring 5. Depending on the object it might not work in all cases.
import com.fasterxml.jackson.databind.ObjectMapper;
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(yourObject));
the output would look like
{
"id" : 1,
"fieldOne" : "string"
}
Here are more examples using Jackson
If you use GSON instead It might look like
Gson gson = new Gson();
System.out.println(gson.toJson(yourObject));
If you are using project Lombok you could use the #ToString annotation and generate a standard toString() method without adding boilerplate.
import lombok.ToString;
#ToString
public class LoginDto {
private String user;
private String pass;
}
...
System.out.println(loginDto.toString());
// LoginDto(user=x#xxx.x, pass=xxxxx)

WPF ItemsControl doesnt update when I add a new item in ItemsSource [duplicate]

I've got a WCF service that passes around status updates via a struct like so:
[DataContract]
public struct StatusInfo
{
[DataMember] public int Total;
[DataMember] public string Authority;
}
...
public StatusInfo GetStatus() { ... }
I expose a property in a ViewModel like this:
public class ServiceViewModel : ViewModel
{
public StatusInfo CurrentStatus
{
get{ return _currentStatus; }
set
{
_currentStatus = value;
OnPropertyChanged( () => CurrentStatus );
}
}
}
And XAML like so:
<TextBox Text="{Binding CurrentStatus.Total}" />
When I run the app I see errors in the output window indicating that the Total property cannot be found. I checked and double checked and I typed it correctly. The it occurred to me that the errors specifically indicate that the 'property' cannot be found. So adding a property to the struct made it work just fine. But this seems odd to me that WPF can't handle one-way binding to fields. Syntactically you access them the same in code and it seem silly to have to create a custom view model just for the StatusInfo struct. Have I missed something about WPF binding? Can you bind to a field or is property binding the only way?
Binding generally doesn't work to fields. Most binding is based, in part, on the ComponentModel PropertyDescriptor model, which (by default) works on properties. This enables notifications, validation, etc (none of which works with fields).
For more reasons than I can go into, public fields are a bad idea. They should be properties, fact. Likewise, mutable structs are a very bad idea. Not least, it protects against unexpected data loss (commonly associated with mutable structs). This should be a class:
[DataContract]
public class StatusInfo
{
[DataMember] public int Total {get;set;}
[DataMember] public string Authority {get;set;}
}
It will now behave as you think it should. If you want it to be an immutable struct, that would be OK (but data-binding would be one-way only, of course):
[DataContract]
public struct StatusInfo
{
[DataMember] public int Total {get;private set;}
[DataMember] public string Authority {get;private set;}
public StatusInfo(int total, string authority) : this() {
Total = total;
Authority = authority;
}
}
However, I would first question why this is a struct in the first place. It is very rare to write a struct in .NET languages. Keep in mind that the WCF "mex" proxy layer will create it as a class at the consumer anyway (unless you use assembly sharing).
In answer to the "why use structs" reply ("unknown (google)"):
If that is a reply to my question, it is wrong in many ways. First, value types as variables are commonly allocated (first) on the stack. If they are pushed onto the heap (for example in an array/list) there isn't much difference in overhead from a class - a small bit of object header plus a reference. Structs should always be small. Something with multiple fields will be over-sized, and will either murder your stack or just cause slowness due to the blitting. Additionally, structs should be immutable - unlesss you really know what you are doing.
Pretty much anything that represents an object should be immuatable.
If you are hitting a database, the speed of struct vs class is a non-issue compared to going out-of-process and probably over the network. Even if it is a bit slower, that means nothing compared to the point of getting it right - i.e. treating objects as objects.
As some metrics over 1M objects:
struct/field: 50ms
class/property: 229ms
based on the following (the speed difference is in object allocation, not field vs property). So about 5x slower, but still very, very quick. Since this is not going to be your bottleneck, don't prematurely optimise this!
using System;
using System.Collections.Generic;
using System.Diagnostics;
struct MyStruct
{
public int Id;
public string Name;
public DateTime DateOfBirth;
public string Comment;
}
class MyClass
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
public string Comment { get; set; }
}
static class Program
{
static void Main()
{
DateTime dob = DateTime.Today;
const int SIZE = 1000000;
Stopwatch watch = Stopwatch.StartNew();
List<MyStruct> s = new List<MyStruct>(SIZE);
for (int i = 0; i < SIZE; i++)
{
s.Add(new MyStruct { Comment = "abc", DateOfBirth = dob,
Id = 123, Name = "def" });
}
watch.Stop();
Console.WriteLine("struct/field: "
+ watch.ElapsedMilliseconds + "ms");
watch = Stopwatch.StartNew();
List<MyClass> c = new List<MyClass>(SIZE);
for (int i = 0; i < SIZE; i++)
{
c.Add(new MyClass { Comment = "abc", DateOfBirth = dob,
Id = 123, Name = "def" });
}
watch.Stop();
Console.WriteLine("class/property: "
+ watch.ElapsedMilliseconds + "ms");
Console.ReadLine();
}
}
I can only guess why they only support properties: perhaps because it seems to be a universal convention in the .NET framework never to expose mutable fields (probably to safeguard binary compatibility), and they somehow expected all programmers to follow the same convention.
Also, although fields and properties are accessed with the same syntax, data binding uses reflection, and (so I've heard) reflection must be used differently to access fields than to access properties.

Dapper - two columns to be switched over time (controlled by config value)

I have the following problem:
A several tables with "data", "token_data" columns that switch their values over time
Phases:
In the current phase 0, there is only "data" column (clear data).
In phase 1 there will be "data", "token_data" columns.
In the phase 2, there will be "token_data", "clear_data" columns.
In the last phase 3, there should be only "data" column (by that
time it should be tokenized).
We currently have all dapper/db models with phase 0 in mind.
Is there a way to prepare Dapper models for all 4 phases? I was looking for OptionalColumn attribute, but couldn't find one.
Ideally there would be a global config switch that would control which Dapper model property represents the tokenized "data" column.
Like:
// Not good
[Column("Name")]
public string Name
{
get { return AppSettings.TokenizationEnabled ? this.TokenName : _name; }
set { _name = value; }
}
It's not 100% clear what you need to do. For example, why you can'y just created a class with all properties, and, depending on the phase, return the correct data for that phase. Something like:
class MyData {
public int Phase;
public String Data { private get; public set; }
public String Token_Data { private get; public set; }
public String Clean_Data { private get; public set; }
public String GetData()
{
switch(Phase): {
case 1: return Token_Data; break;
case 2: return Clean_data; break;
default: return Data; break
}
}
Aside from that, anyway, I think the feature called "Type Switching per Row" can help you: https://github.com/StackExchange/Dapper#type-switching-per-row

Serialization of a OxyPlot Chart to XAML

I generated a PageBuilder different UI-Models (TextBlocks, Images) for creating a XAMLLayout.
For this I placed all my Elements on a Canvas and save the complete Canvas to a Xaml-File (With the XamlWriter.Save-Method).
Now I need to generate Charts and serialize them.
With the OxyPlot-Library i used this code for generating the code via runtime.
OxyPlot.Wpf.PlotView pv = new OxyPlot.Wpf.PlotView();
OxyPlot.PlotModel pm = new OxyPlot.PlotModel();
pv.Height = 300;
pv.Width = 500;
pv.Background = Brushes.Red;
pm.Title = "Test";
pm.Series.Add(new OxyPlot.Series.FunctionSeries(Math.Cos, 0, 10, 0.1, "cos(x)"));
pv.Model = pm;
canvas.Children.Add(pv);
For the serialisation I just call my Canvas and serialize the whole objects like this this:
XamlWriter.Save(canvas);
Durring this process I got an exception:
System.InvalidOperationException: "The generic type" System.Collections.Generic.List`1 [OxyPlot.OxyColor] "can not be serialized."
At this point, Generic type only has very limited support in xaml.
XamlWriter cannot serialize a property of a generic list type. You can try the following workaround to fix the issue.
public class OxyPlot
{
public OxyColors OxyColor { get; set; }
}
public class OxyColors : List<OxyColor>
{
}
public class OxyColor
{
}

How to deserialize several nested Json arrays (more than 2) using DataContractJsonSerializer (Windows Phone 7)

I need to deserialize the next Json string that has several nested Json arrays:
{"d1":[["11791452",[["980",""]]],["11791453",[["1060",""],["1140",""],["1220",""],["1300",""]]],["11791454",[["1070",""]]]]}
I try to do it in several steps, so far I'm able to deserialize three levels of nested arrays. As follow:
{"aOaOa":[[["1060",""],["1140",""],["1220",""],["1300",""]]]}
public class ThreeSimpleNestedArrays
{
public List<List<string[]>> aOaOa; //array of arrays of arrays
public ThreeSimpleNestedArrays()
{
aOaOa = new List<List<string[]>>();
}
}
But the problem arise when I add the extra string in the array structure:
{"TEST": [["11791453",[["1060",""],["1140",""],["1220",""],["1300",""]]],["123456",[["0","1"],["2","3"]]]]}
public class ComplexNestedArray
{
public List<Dictionary<string,List<string[]> >> TEST;
public ComplexNestedArray()
{
TEST = new List<Dictionary<string, List<string[]>>>();
}
}
I'm getting the next error message:
"Unable to cast object of type 'System.String' to type 'System.Collections.Generic.Dictionary`2[System.String,System.Object]'."
What am I missing?
Can anybody suggest a way to deserialize an object like this nested within Json arrays using DataContractJsonSerializer?
The code I use to deserialize is the next:
//Works
DataContractJsonSerializer dcJsonSer = new DataContractJsonSerializer(typeof(ThreeSimpleNestedArrays));
ThreeSimpleNestedArrays root = (ThreeSimpleNestedArrays)dcJsonSer.ReadObject(str);
//Don't work
DataContractJsonSerializer dcJsonSer = new DataContractJsonSerializer(typeof(ComplexNestedArray));
ComplexNestedArray root = (ComplexNestedArray)dcJsonSer.ReadObject(str);
Btw, I'm able to deserilize the object when it is serilized as a Json Object as follow:
{"TEST": [{"s": "11791453","aOa": [["1060",""],["1140",""],["1220",""],["1300",""]]},{"s": "123456","aOa":[["0","1"],["2","3"]]}]}
using a class with two members (a string "s" and a List of string[] "aOa"), but without the names, when the object is serialized as an array, I'm unable to do it.
Any suggestion?
Ok, it looks like the DataContractJsonSerializer is smarter than I though .
It turns out that the way to deserialize that kid of nested objects array is with a class like this:
public class ComplexNestedArray
{
//{"TEST": [["11791453",[["1060",""],["1140",""],["1220",""],["1300",""]]],["123456",[["0","1"],["2","3"]]]]}
public List<List<object>> TEST { get; set; }
}
After that, it is only a mater to do a couple of for cycles and casts to the appropriate class structure.
Btw, This is a MUST in your toolbox in case you have to deal with Json:
json2csharp
Here is my solution. However I'll try to add later a way for your full json:
class Program {
static void Main(string[] args) {
new Program();
}
public Program() {
string full = "{\"d1\":[[\"11791452\",[[\"980\",\"\"]]],[\"11791453\",[[\"1060\",\"\"],[\"1140\",\"\"],[\"1220\",\"\"],[\"1300\",\"\"]]],[\"11791454\",[[\"1070\",\"\"]]]]}";
string simple1 = "{\"aOa\":[[\"1060\",\"\"],[\"1140\",\"\"],[\"1220\",\"\"],[\"1300\",\"\"]]}";
string simple2 = "{\"aOaOa\":[[[\"1060\",\"\"],[\"1140\",\"\"],[\"1220\",\"\"],[\"1300\",\"\"]]]}";
DataContractJsonSerializer d1 = new DataContractJsonSerializer(typeof(S1));
S1 r1 = (S1)d1.ReadObject(new MemoryStream(Encoding.Default.GetBytes(simple1)));
DataContractJsonSerializer d2 = new DataContractJsonSerializer(typeof(S2));
S2 r2 = (S2)d2.ReadObject(new MemoryStream(Encoding.Default.GetBytes(simple2)));
Console.WriteLine("done");
Console.ReadKey();
}
[DataContract]
class S1 {
[DataMember]
List<List<String>> aOa;
}
[DataContract]
class S2 {
[DataMember]
List<List<List<string>>> aOaOa;
}
}

Resources