我有许多不可变的值类型类,例如EmailAddress,它们确保任何非空实例都是有效的。我希望在使用MongoDB C驱动程序持久化时,将这些类型对象的序列化控制为标准字符串表示("[email protected]")。
我已经尝试实现了IBsonSerilizer,但是它只允许根级别的对象或数组。我能够用json.net实现正确的json系列化,我是否应该采取不同的方法?

最佳答案

我想你是指类似这样的emailaddress类:

[BsonSerializer(typeof(EmailAddressSerializer))]
public class EmailAddress
{
    private string _value;

    public EmailAddress(string value)
    {
        _value = value;
    }

    public string Value
    {
        get { return _value; }
    }
}

我使用了一个属性将emailaddress类链接到自定义序列化程序,该序列化程序可以如下实现:
public class EmailAddressSerializer : BsonBaseSerializer
{
    public override object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
    {
        if (bsonReader.GetCurrentBsonType() == BsonType.Null)
        {
            bsonReader.ReadNull();
            return null;
        }
        else
        {
            var value = bsonReader.ReadString();
            return new EmailAddress(value);
        }
    }

    public override void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
    {
        if (value == null)
        {
            bsonWriter.WriteNull();
        }
        else
        {
            var emailAddress = (EmailAddress)value;
            bsonWriter.WriteString(emailAddress.Value);
        }
    }
}

不能将电子邮件地址序列化为根文档(因为它不是文档…)。但是你可以使用嵌入在其他文档中的电子邮件地址。例如:
public class Person
{
    public int Id { get; set; }
    public EmailAddress EmailAddress { get; set; }
}

可以使用如下代码进行测试:
var person = new Person { Id = 1, EmailAddress = new EmailAddress("[email protected]") };
var json = person.ToJson();
var rehyrdated = BsonSerializer.Deserialize<Person>(json);

生成的json/bson文档是:
{ "_id" : 1, "EmailAddress" : "[email protected]" }

09-12 00:04