mongodb-csharp


How to force serialization of decimal values inside dictionaries as doubles in mongodb csharp driver?


I have the following dictionary:
var dict = new Dictionary<string, object> {
{ "decimal", 3.503m },
{ "int", 45 }
};
var serializedString = dict.ToJson();
By default that is serialized as:
{ "decimal" : { "_t" : "System.Decimal", "_v" : "3.503" }, "int" : 45 }
If I override DecimalSerializer as:
BsonSerializer.RegisterSerializer<decimal>(new DecimalSerializer().WithRepresentation(BsonType.Double));
That only influences on how "_v" value is serialized, e.g.:
{ "decimal" : { "_t" : "System.Decimal", "_v" : 3.503 }, "int" : 45 }
Expected result:
{ "decimal" : 3.503, "int" : 45 }
Please advise
The cause of the .Net types in the bson, is the lack of type in the dictionary. The Bson serializers are trying to get enough state to restore the original object of the items in the dictionary. From the context (the dictionary) they are of type "object", so the .Net type is inserted to know enough when deserializing.
The following solutions answer your question but lose the type information for deserializing.
Solution 1: Change the dictionary type to <string, decimal>
var dict = new Dictionary<string, decimal> {
{ "decimal", 3.503m },
{ "int", 45 }
};
var serializedString = dict.ToJson();
Results in: { "decimal" : "3.503", "int" : "45" }
With your override of the decimal serializer, you get the expected result.
{ "decimal" : 3.503, "int" : 45 }
Solution 2: Change the dictionary type to <string, double>
var dict = new Dictionary<string, double> {
{ "decimal", (double)3.503m },
{ "int", 45 }
};
var serializedString = dict.ToJson();
Results in the expected result: { "decimal" : 3.503, "int" : 45 }
Solution 3: Use custom serializer
public class MyDictionarySerializer : SerializerBase<Dictionary<string, object>>
{
public override void Serialize(MongoDB.Bson.Serialization.BsonSerializationContext context, MongoDB.Bson.Serialization.BsonSerializationArgs args, Dictionary<string, object> dictionary)
{
context.Writer.WriteStartArray();
foreach (var item in dictionary)
{
context.Writer.WriteStartDocument();
context.Writer.WriteString(item.Key);
// TODO your converstions from object to double
var value = (double)item.Value;
context.Writer.WriteDouble(value);
context.Writer.WriteEndDocument();
}
context.Writer.WriteEndArray();
}
public override Dictionary<string, object> Deserialize(MongoDB.Bson.Serialization.BsonDeserializationContext context, MongoDB.Bson.Serialization.BsonDeserializationArgs args)
{
context.Reader.ReadStartArray();
var result = new Dictionary<string, object>();
while (true)
{
try
{
//this catch block only need to identify the end of the Array
context.Reader.ReadStartDocument();
}
catch (Exception exp)
{
context.Reader.ReadEndArray();
break;
}
var key = context.Reader.ReadString();
double value = context.Reader.ReadDouble();
result.Add(key, value);
context.Reader.ReadEndDocument();
}
return result;
}
}
As another option, it's possible to override object serializer
public class DecimalsOverridingObjectSerializer : ObjectSerializer
{
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value) {
if (value != null && value is decimal) {
base.Serialize(context, args, Convert.ToDouble(value));
} else {
base.Serialize(context, args, value);
}
}
}
BsonSerializer.RegisterSerializer(typeof(object), new DecimalsOverridingObjectSerializer());
that still will not work for Hashtables.
Possible workaround for Hashtables:
public class DecimalsOverridingDictionarySerializer<TDictionary>:
DictionaryInterfaceImplementerSerializer<TDictionary>
where TDictionary : class, IDictionary, new()
{
public DecimalsOverridingDictionarySerializer(DictionaryRepresentation dictionaryRepresentation)
: base(dictionaryRepresentation, new DecimalsOverridingObjectSerializer(), new DecimalsOverridingObjectSerializer())
{ }
}
BsonSerializer.RegisterSerializer(typeof(Hashtable), new DecimalsOverridingDictionarySerializer<Hashtable>(DictionaryRepresentation.Document));

Related Links

Is there Document Validator available for MongoDB using C# driver?
MongoDB projection on missing field on Document
MongoDB faceted search
Mongodb c# InsertOne() - How to Handle exception
How to force serialization of decimal values inside dictionaries as doubles in mongodb csharp driver?
How do I use in $in operator using the 2.0 version of the C# mongodb driver?
What is the purpose of the MaxConnectionLifeTime setting
MongoDB C# driver throws timeout exception when trying to connect to replica set
Serialize Dictionary<long, VALUE> to BSON documents
Using a Regex against a simple list with `ElemMatch` in MongoDB .NET
projection wont work in mongodb c# driver
BsonClassMapSerializer already registered for AbstractClassSerializer
MongoDb C# Driver 2.0 Coalesce (or equivalent)?
MongoDB dynamic update of collection when changes occurs in another collection
MongoDB C# 2.0 TimeoutException
MongoDB C# 2.0 upgrade

Categories

HOME
beautifulsoup
xml
microsoftgraph
facebook-oauth
twitter-bootstrap-3
hyperlink
eslint
alexa-skills-kit
devise
xbee
web-hosting
visual-studio-emulator
onclick
boto3
extjs4.2
augeas
commonjs
windows-ce
xcodebuild
libc
frequency-distribution
plink
http-post
event-sourcing
dimensional-modeling
asciidoctor-pdf
articulate-storyline
react-toolbox
pchart
flask-sqlalchemy
slidetoggle
pylons
spotipy
sinch
subclass
failover
realm-mobile-platform
aws-codecommit
recurring-events
cart
rselenium
hreflang
activexobject
browser-extension
lint
reactivekit
release
ods
mongoose-schema
p4merge
doc
apollostack
knime
jide
globalize
reportservice2010
fclose
openblas
page-replacement
cup
google-photos
filenet
restore
cvxpy
hclust
jclouds
respondcms
php-socket
fuzzywuzzy
contentcontrol
design-principles
grgit
rewrite
rubaxa-sortable
android-launcher
text-search
dock
slash
uncompress
liquid-layout
bufferedinputstream
android-broadcast
java-security
nodelist
sip-server
entry-point
paw
nsmenu
create.js
ignite-ui
live555
jeromq
cmmi
route-provider
dolby-audio-api
adobe-media-server
uipagecontrol
unattended-processing
cloudfiles
svk
addchild
zend-rest
blender-2.49
filesystemobject
visualj#
sun
todos
int64
entitykey
wcf-proxy

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App