MongoDBをC#で操作しているシステムで、あるオブジェクトをJSON.netでJSONにシリアライズしてやりとりするようなことをしていました。
もともとBSONのままやりとりしていたんですが、ちょっと別の環境とデータを連係させるのにJSONの方が都合がいいこともあり、C#のシステムの外とやりとりする部分をJSON.netでシリアライズ/デシリアライズするように書き直しておりました。
これ自体大して難しいことではなかったのですが、動かしてみるとどうしてもObjectIdが全部0(Empty値)になってしまうのです。 JSONの中身をよくよく見てみると、
\"_id\":
{
\"Timestamp\":1385017265,
\"Machine\":697085,
\"Pid\":9400,
\"Increment\":11974837,
\"CreationTime\":\"\\/Date(1385017265000)\\/\"
}
なんかこのようなことに……これってObjectIdを生成する元のパラメータですね。 JSON.netのJsonConvert.SerializeObjectで文字列にするとこうなってしまいます。これがそのまま外に出てからDeserializeしてもちゃんと元に戻らないと言うことですね。
そのオブジェクトは、中身にList
相当悩んだのですが、結局原因は「JSON.netのバージョンが低かった!」と言うことでした。 もう、情けないやらなにやら……
何でこうなったかというと、作っているシステムには、JSON.netの4.0なにがしかが入っていました。 なんか別のパッケージを入れたときに一緒に入ったと思われるのですが、なんか別のプロジェクトに入れたのを勘違いでもしたのか、新しいものを入れたんだと思ってそのまま使っておりました。 そして、検証用のプログラムの方は、全く新しいプロジェクトでパッケージを新しくセットして始めたので、5.0.8が入りました。
いやー、つまらないことではまりました。
で、あとはおまけなんですが、C#でMongoDBのドキュメント用にクラスを作る場合、これまでObjectIdを格納するフィールドには、MongoDB.Bson.ObjectId型のフィールドを使っていたのですが、これをそのままにしておくとJSONからデシリアライズする際にキャストできないって叱られるようになります。
なんかAttributes(?)なんかで変換するアダプタを指定して……みたいな方法も見たんですが、結局……
- using MongoDB.Bson.Serialization.Attributes; する
- idの部分をstring型にする
- [BsonRepresentation(BsonType.ObjectId)]をつける
- ドキュメントのidになるようなものには、[BsonId]もつけておけばいいかな という方法で、プログラム中では全部stringで扱うように変更しました。
あとなんか日付の部分も若干何か気になることもないでもないですねぇ。