IMO这是Dart的主要缺点,考虑到其以Web应用程序为重点,这令人惊讶。我本以为在标准库中拥有JSON支持,这意味着将类与JSON进行序列化就像水一样工作,不幸的是JSON支持似乎不完整,在这里似乎选择使用松散类型的地图或遭受苦难通过不必要的样板配置您的标准(PODO)类以按预期进行序列化。
没有反射和镜像支持
由于流行的Dart平台(例如Flutter)不支持反射/镜像,因此您唯一的选择是使用代码生成解决方案。我们在ServiceStack
对Dart和Flutter的本机支持中采用的方法使您可以从远程URL为所有ServiceStack服务生成类型化的Dart模型,例如:
$ npm install -g @servicestack/cli$ dart-ref https://www.techstacks.io
在.NET Core和任何.NET流行的托管选项中受支持。
上面的示例使用从www.techstacks.io/types/dart端点生成的DTO,为.NET
Core 2.0 TechStacks项目生成Typed API
。这将按照Dart的JsonCodec模式生成模型,您可以在其中通过提供命名的构造函数和实例方法为Dart模型自定义序列化,这是生成的DTO之一的示例:
fromJson``toJson()
class UserInfo implements IConvertible{ String userName; String avatarUrl; int stacksCount; UserInfo({this.userName,this.avatarUrl,this.stacksCount}); UserInfo.fromJson(Map<String, dynamic> json) { fromMap(json); } fromMap(Map<String, dynamic> json) { userName = json['userName']; avatarUrl = json['avatarUrl']; stacksCount = json['stacksCount']; return this; } Map<String, dynamic> toJson() => { 'userName': userName, 'avatarUrl': avatarUrl, 'stacksCount': stacksCount }; TypeContext context = _ctx;}使用此模型,您可以使用Dart内置的json:convert
API将模型序列化和反序列化为JSON,例如:
//Serializationvar dto = new UserInfo(userName:"foo",avatarUrl:profileUrl,stacksCount:10);String jsonString = json.enpre(dto);//DeserializationMap<String,dynamic> jsonObj = json.depre(jsonString);var fromJson = new UserInfo.fromJson(jsonObj);
这种方法的好处是,它可以在 所有Dart平台上使用 ,包括Flutter和AngularDart或带有和不带有Dart 2的“强模式”的Dart
Web应用程序。
生成的DTO也可以与servicestack的Dart包一起使用,以启用端到端类型化解决方案,该解决方案需要将JSON序列化进出您的类型化DTO,例如:
var client = new JsonServiceClient("https://www.techstacks.io");var response = await client.get(new GetUserInfo(userName:"mythz"));有关更多信息,请参阅ServiceStack的本机Dart支持文档。
飞镖镜
如果您在可提供镜像支持的平台上使用Dart,那么我发现使用Mixin花费的精力最少,例如:
import 'dart:convert';import 'dart:mirrors';abstract class Serializable { Map toJson() { Map map = new Map(); InstanceMirror im = reflect(this); ClassMirror cm = im.type; var decls = cm.declarations.values.where((dm) => dm is VariableMirror); decls.forEach((dm) { var key = MirrorSystem.getName(dm.simpleName); var val = im.getField(dm.simpleName).reflectee; map[key] = val; }); return map; }}您可以将其与PODO类混合使用:
class Customer extends Object with Serializable{ int Id; String Name;}您现在可以使用
JSON.enpre:
var c = new Customer()..Id = 1..Name = "Foo";print(JSON.enpre(c));
结果:
{"Id":1,"Name":"Foo"}注意:[请参阅使用镜像的警告](https://www.dartlang.org/articles/reflection-with-
mirrors/)



