Flutter 具有空安全性的颤振日期时间序列化程序

Flutter 具有空安全性的颤振日期时间序列化程序,flutter,datetime,dart,built-value,Flutter,Datetime,Dart,Built Value,我在flatter中使用内置值,两个库都是空安全的 built_value_generator: ^8.0.4 built_value: ^8.0.4 在我的模型中,我有几个DateTime对象,它们都可以为空。为了序列化这些,我使用了一个自定义序列化程序,如果字符串为null或空,它将返回null。但它抛出了一个例外 Deserializing '[data, [{_id: 609e6ea910fd591efebd61a3, booking_id: 609e6ea99fe023fd

我在flatter中使用内置值,两个库都是空安全的

built_value_generator: ^8.0.4
built_value: ^8.0.4
在我的模型中,我有几个DateTime对象,它们都可以为空。为了序列化这些,我使用了一个自定义序列化程序,如果字符串为null或空,它将返回null。但它抛出了一个例外

  Deserializing '[data, [{_id: 609e6ea910fd591efebd61a3, booking_id: 
  609e6ea99fe023fde50aa375,...' to 'BookingResponse' failed due to: Deserializing '[{_id: 
  609e6ea910fd591efebd61a3, booking_id: 609e6ea99fe023fde50aa375, client...' to 
  'BuiltList<Booking>' failed due to: Deserializing '[_id, 609e6ea910fd591efebd61a3, 
  booking_id, 609e6ea99fe023fde50aa375, client,...' to 'Booking' failed due to: type 'Null' 
  is not a subtype of type 'DateTime' in type cast
  
使用下面的序列化程序(将返回null)

这表明它不能为null,但它也有

DateTime? _booking_date;
DateTime? get booking_date => _$this._booking_date;
set booking_date(DateTime? booking_date) =>
  _$this._booking_date = booking_date;

这让我觉得可能是这样的,你知道为什么会抛出异常吗?

我将此报告为内置值生成器中的一个bug:

生成的代码对DateTime的转换不正确,但它应该对DateTime?进行转换


在生成的代码中将强制转换更改为DateTime时?反序列化工作正常。

是否将«specifiedType:const FullType(DateTime))更改为DateTime»?例如,将其替换为«specifiedType:const FullType(DateTime))作为日期时间?»这是生成的代码,但我不认为任何指定的完整类型的更改都应该被解析为,在实现中,它会在尝试将其解析为该类型之前检查其是否为null。我可以通过返回DateTime使其不会崩溃。now()从反序列化方法中的else子句来看,这肯定是内置值生成器中的bug。因此,我建议在其GitHub中创建一个问题。我尝试了您的示例,并注意到它只在空字符串的情况下发生。若缺少字段或字段显式为空,则输入可以反序列化。如果你能控制你正在使用的API,我建议你在API端修复它——用空字符串来表示空值是个坏主意。是的,我已经告诉过他们了,我希望他们能做出这样的改变,不过谢谢你的理智检查,
class DateTimeSerializer implements PrimitiveSerializer<DateTime?> {
  @override
  DateTime? deserialize(Serializers serializers, Object? serialized, {FullType specifiedType = FullType.unspecified}) {
   logger('DateTime.deserialize: $serialized');
    if (serialized != null && serialized is String && serialized.isNotEmpty) {
      logger('DateTime.deserialize parse: $serialized');
      return DateTime.parse(serialized).toLocal();
    } else {
      return null;
    }
  }

  @override
  Object serialize(Serializers serializers, DateTime? object, {FullType specifiedType = FullType.unspecified}) {
   logger('DateTime.serialize: $object');
    if (object != null) {
      return object.toUtc().toIso8601String();
    } else {
      return Object();
    }
  }

  @override
  Iterable<Type> get types => [DateTime];

  @override
  String get wireName => 'DateTime';
}
     case 'booking_date':
      result.booking_date = serializers.deserialize(value,
          specifiedType: const FullType(DateTime)) as DateTime;
      break;
DateTime? _booking_date;
DateTime? get booking_date => _$this._booking_date;
set booking_date(DateTime? booking_date) =>
  _$this._booking_date = booking_date;