The C# driver supported serializing the .NET Decimal type long before the server added a Decimal128 data type. In order to do so Decimal values were serialized as strings.
So for example, the following class:
public class C
{
public int Id { get; set; }
public decimal D { get; set; }
}
Would be serialized as:
{ _id : 1, D : "1.5" }
When you read this back in your C# program the string will be parsed back into a .NET Decimal value. But server side it is a string, which is why you are seeing that server side error message.
For backward compatibility reasons the C# driver still (by default) serializes .NET Decimal values as strings. You can opt in to serializing .NET Decimal values as BSON Decimal128 values like this:
public class C
{
public int Id { get; set; }
[BsonRepresentation(BsonType.Decimal128)]
public decimal D { get; set; }
}
Finally, be aware that the .NET Decimal type and the BSON Decimal128 type are not exactly the same. The range of BSON Decimal128 is much larger than the range of .NET Decimal. That means that all .NET Decimal values can be safely stored in a BSON Decimal128 field, but not all BSON Decimal128 values can be converted to .NET Decimal values.