簡體   English   中英

自定義序列化程序,可為MongoDb處理可為空和不能為空的類型

[英]Custom serializer that processes both nullable and not nullable types for MongoDb

我需要使用IBsonSerializer實現自定義序列化程序。

那就是我所做的:

internal class MyCustomDateTimeSerializer : IBsonSerializer
{
   public object Deserialize(BsonDeserializationContext context, 
         BsonDeserializationArgs args)
   {
       // Deserialization logic
   }

   public void Serialize(BsonSerializationContext context, 
         BsonSerializationArgs args, object value)
   {
       // Serialization logic
   }

   public Type ValueType => typeof(DateTime);
}

然后在BsonSerializerAttribute中使用它:

[BsonSerializer(typeof(MyCustomDateTimeSerializer))]

我的問題是我想序列化/反序列化DateTime和可空的DateTime。

我的CustomSerializer的ValueType設置為typeof(DateTime),因此我得到如下異常:

序列化器的值類型為System.DateTime,並且與成員類型System.Nullable`1 [[System.DateTime ..

我沒有找到解決此問題的方法。 當然,我可以為Nullable DateTime和DateTime創建兩個不同的類,但是也許還有另一種選擇?

如果您在MongoDB.Bson庫中檢查SetSerializer方法的源代碼,您會發現它對成員類型的檢查非常簡單:

if (serializer.ValueType != _memberType)
{
    var message = string.Format("Value type of serializer is {0} and does not match member type {1}.", serializer.ValueType.FullName, _memberType.FullName);
    throw new ArgumentException(message, "serializer");
}

該代碼檢查類型相等性,並且沒有辦法欺騙它,並認為DateTimeNullable<DateTime>是相等的。

但是,您可以使用一種解決方案來擁有一個序列化程序類,並避免重復代碼。 您可以將序列化器設為通用類,並強制其僅接受DateTimeNullable<DateTime>作為類型參數。 這是一個示例:

internal class MyCustomDateTimeSerializer<TDateTime> : IBsonSerializer
{
    static MyCustomDateTimeSerializer()
    {
        if (typeof(TDateTime) != typeof(DateTime) && typeof(TDateTime) != typeof(DateTime?))
        {
            throw new InvalidOperationException($"MyCustomDateTimeSerializer could be used only with {nameof(DateTime)} or {nameof(Nullable<DateTime>)}");
        }
    }

    public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        // Deserialization logic
    }

    public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
    {
        // Serialization logic
    }

    public Type ValueType => typeof(TDateTime);
}

public class SomeDocument
{
    // ...

    [BsonSerializer(typeof(MyCustomDateTimeSerializer<DateTime>))]
    public DateTime Date1 { get; set; }

    [BsonSerializer(typeof(MyCustomDateTimeSerializer<DateTime?>))]
    public DateTime? Date2 { get; set; }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM