Reputation: 9859
I've had a good experience with serialization on C#, and after searching and testing some Dart libraries I feel there isn't a really satisfactory answer in general.
Id also like anybody that reads this to please post any new information, even if the post gets old.
Upvotes: 3
Views: 1942
Reputation: 854
I realize this is an old question, but if you're coming here in 2019+ there is an excellent code-generation solution I've found:
https://pub.dartlang.org/packages/json_serializable
Judging by the git-hub repository I'd say this is the "official" solution as well.
It works using the annotations @JsonSerializable
and @JsonKey
to control serialization. In my experience it seems to flawlessly handle inheritance and the like as well. It automatically generates serialization and decentralization functions when you build the project.
Upvotes: 3
Reputation: 486
Generally, there is a move away from mirrors-based solutions to codegen-based solutions, particularly based on package:source_gen. This is because codegen can provider smaller and faster runtimes than mirrors.
One package that uses codegen for serialization is built_value:
https://github.com/google/built_value.dart
With built_value your model classes look like this:
abstract class Account implements Built<Account, AccountBuilder> {
static Serializer<Account> get serializer => _$accountSerializer;
int get id;
String get name;
BuiltMap<String, JsonObject> get keyValues;
factory Account([updates(AccountBuilder b)]) = _$Account;
Account._();
}
Note that built_value isn't just about serialization -- it also provides operator==, hashCode, toString, and a builder class.
Upvotes: 1
Reputation: 10875
Dart has an implementation to encode and decode Maps, Lists, and primitive types. You can find examples on this article. If you're looking for speed, this is probably the fastest, as they implement the json conversion in native C/C++ - libraries made by authors are usually written in Dart, and will be slower.
The disadvantage of the JSON.encode
and JSON.decode
is that they can't take any other Objects besides the ones mentioned above without having the toJson and fromJson methods.
Fortunately, there's libraries that take advantage of reflection in Dart to make it easier. I made a small library myself, to serialize and deserialize objects to and from JSON without any extra code to your classes. You can find it here. In addition to the above solutions to your issue, there's many you can find on the Dart pub website.
Upvotes: 0
Reputation: 966
Currently, you can use redstone_mapper to convert between Dart objects and JSON. This package is a plugin to the Redstone.dart framework, but can be used without it. There's also other options available on Pub
Upvotes: 2
Reputation: 9859
I am currently serializing with exportable and deserializing with morph.
Upvotes: 0
Reputation: 42343
For now, the best option is probably to use the Smoke library.
It's a subset of the Mirrors functionality but has both a Mirrors-based and a Codegen-based implementation. It's written by the PolymerDart team, so it's as close to "Official" as we're going to get.
While developing, it'll use the Mirrors-based encoding/decoding; but for publishing you can create a small transformer that will generate code.
Seth Ladd created a code sample here, which I extended slightly to support child-objects:
abstract class Serializable {
static fromJson(Type t, Map json) {
var typeMirror = reflectType(t);
T obj = typeMirror.newInstance(new Symbol(""), const[]).reflectee;
json.forEach((k, v) {
if (v is Map) {
var d = smoke.getDeclaration(t, smoke.nameToSymbol(k));
smoke.write(obj, smoke.nameToSymbol(k), Serializable.fromJson(d.type, v));
} else {
smoke.write(obj, smoke.nameToSymbol(k), v);
}
});
return obj;
}
Map toJson() {
var options = new smoke.QueryOptions(includeProperties: false);
var res = smoke.query(runtimeType, options);
var map = {};
res.forEach((r) => map[smoke.symbolToName(r.name)] = smoke.read(this, r.name));
return map;
}
}
Currently, there is no support to get generic type information (eg. to support List) in Smoke; however I've raised a case about this here:
https://code.google.com/p/dart/issues/detail?id=20584
Until this issue is implemented, a "good" implementation of what you want is not really feasible; but I'm hopeful it'll be implemented soon; because doing something as basic as JSON serialisation kinda hinges on it!
Alan Knight is also working on a Serialisation package, however I found it to lack support for things as simple as converting datetimes to strings, and the solution seemed rather verbose for something so basic.
For now, in my own project, I've gone with codegenning our json serialisation (in the form of toMap and fromMap methods) since we would already have C# versions of our classes for the server side. If time allows, I'd like to tidy those code up and make a NuGet package (it supports nested objects, arrays, excluding properties, etc.).
Upvotes: 4
Reputation: 657376
There is no "one size fits all" serialization solution. For a lengthy discussion see https://groups.google.com/a/dartlang.org/forum/#!searchin/misc/serialization/misc/0pv-Uaq8FGI/5iMrzOrlUKwJ
Upvotes: 1