いくつかのことが起こっています。主なものは、タイプに関係なく入力を消費する必要があることです。そうしないと、逆シリアル化プロセスが同期しなくなります。 nullを処理し、ZipCodesを文字列として書き込む、ZipCodeSerializerと呼ばれるカスタムシリアライザーを作成するシナリオをテストしましたが、入力時に文字列またはintのいずれかを受け入れ、intを文字列に変換します。
このクラスを使用してテストしました:
public class Address
{
public ObjectId Id;
public string ZipCode;
}
そして、これは私が書いたカスタムシリアライザーです:
public class ZipCodeSerializer : BsonBaseSerializer
{
public override object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
{
var bsonType = bsonReader.CurrentBsonType;
switch (bsonType)
{
case BsonType.Null:
bsonReader.ReadNull();
return null;
case BsonType.String:
return bsonReader.ReadString();
case BsonType.Int32:
return bsonReader.ReadInt32().ToString();
default:
var message = string.Format("ZipCodeSerializer expects to find a String or an Int32, not a {0}.", bsonType);
throw new BsonSerializationException(message);
}
}
public override void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
{
if (value == null)
{
bsonWriter.WriteNull();
}
else
{
bsonWriter.WriteString((string)value);
}
}
}
カスタムシリアライザーが接続されていることを確認する必要があります。これは次のように実行できます:
BsonClassMap.RegisterClassMap<Address>(cm =>
{
cm.AutoMap();
cm.GetMemberMap(a => a.ZipCode).SetSerializer(new ZipCodeSerializer());
});
これで、AddressクラスのZipCodeフィールドがカスタムシリアライザーによって処理されるようになります。
BsonDocumentを使用していくつかのテストデータを作成し、テストコレクションに保存されている特定のバージョンのデータを簡単に強制できるようにしました。
collection.Drop();
collection.Insert(new BsonDocument());
collection.Insert(new BsonDocument("ZipCode", BsonNull.Value));
collection.Insert(new BsonDocument("ZipCode", "12345"));
collection.Insert(new BsonDocument("ZipCode", 56789));
mongoシェルを使用したドキュメントは次のようになります。
> db.test.find()
{ "_id" : ObjectId("4f871374e447ad238040e346") }
{ "_id" : ObjectId("4f871374e447ad238040e347"), "ZipCode" : null }
{ "_id" : ObjectId("4f871374e447ad238040e348"), "ZipCode" : "12345" }
{ "_id" : ObjectId("4f871374e447ad238040e349"), "ZipCode" : 56789 }
>
したがって、一部のZipCodeは文字列であり、一部はintであることがわかります(nullもスローされます)。
そしてこれが私のテストコードです:
foreach (var document in collection.FindAll())
{
Console.WriteLine(document.ToJson());
}
そして、テストコードの実行の出力は次のとおりです。
{ "_id" : ObjectId("4f871374e447ad238040e346"), "ZipCode" : null }
{ "_id" : ObjectId("4f871374e447ad238040e347"), "ZipCode" : null }
{ "_id" : ObjectId("4f871374e447ad238040e348"), "ZipCode" : "12345" }
{ "_id" : ObjectId("4f871374e447ad238040e349"), "ZipCode" : "56789" }
Press Enter to continue
データベース内のintであった郵便番号が文字列になっていることに注意してください。
私のテストプログラムの完全なソースコードは、次のURLで入手できます。