// public methods /// <summary> /// Gets the actual type of an object by reading the discriminator from a BsonReader. /// </summary> /// <param name="bsonReader">The reader.</param> /// <param name="nominalType">The nominal type.</param> /// <returns>The actual type.</returns> public Type GetActualType(BsonReader bsonReader, Type nominalType) { // the BsonReader is sitting at the value whose actual type needs to be found var bsonType = bsonReader.GetCurrentBsonType(); if (bsonType == BsonType.Document) { // ensure KnownTypes of nominalType are registered (so IsTypeDiscriminated returns correct answer) BsonSerializer.EnsureKnownTypesAreRegistered(nominalType); // we can skip looking for a discriminator if nominalType has no discriminated sub types if (BsonSerializer.IsTypeDiscriminated(nominalType)) { var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); var actualType = nominalType; if (bsonReader.FindElement(_elementName)) { var context = BsonDeserializationContext.CreateRoot <BsonValue>(bsonReader); var discriminator = BsonValueSerializer.Instance.Deserialize(context); if (discriminator.IsBsonArray) { discriminator = discriminator.AsBsonArray.Last(); // last item is leaf class discriminator } actualType = BsonSerializer.LookupActualType(nominalType, discriminator); } bsonReader.ReturnToBookmark(bookmark); return(actualType); } } return(nominalType); }
// private methods private Type GetActualType(BsonReader bsonReader) { var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); if (bsonReader.FindElement("type")) { var type = bsonReader.ReadString(); bsonReader.ReturnToBookmark(bookmark); switch (type) { case "link": return(typeof(GeoJsonLinkedCoordinateReferenceSystem)); case "name": return(typeof(GeoJsonNamedCoordinateReferenceSystem)); default: var message = string.Format("The type field of the GeoJsonCoordinateReferenceSystem is not valid: '{0}'.", type); throw new FormatException(message); } } else { throw new FormatException("GeoJsonCoordinateReferenceSystem object is missing the type field."); } }
public Type GetActualType(BsonReader bsonReader, Type nominalType) { //Edit: added additional check for list if (nominalType != typeof(IRestriction) && nominalType != typeof(List <IRestriction>)) { throw new Exception("Cannot use IRestrictionDiscriminatorConvention for type " + nominalType); } var ret = nominalType; var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); if (bsonReader.FindElement(ElementName)) { var value = bsonReader.ReadString(); ret = Type.GetType(value); if (ret == null) { throw new Exception("Could not find type from " + value); } //Edit: doing the checking a little different if (!typeof(IRestriction).IsAssignableFrom(ret) && !ret.IsSubclassOf(typeof(IRestriction))) { throw new Exception("type is not an IRestriction"); } } bsonReader.ReturnToBookmark(bookmark); return(ret); }
public Type GetActualType(BsonReader bsonReader, System.Type nominalType) { var currentBsonType = bsonReader.GetCurrentBsonType(); if (bsonReader.State == BsonReaderState.Value) { if (currentBsonType == BsonType.Document) { var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); var type = nominalType; if (bsonReader.FindElement(ElementName)) { var discriminator = BsonValue.ReadFrom(bsonReader).AsString; try { if (discriminator == "Typed") { type = typeof(TypedSettings <>); bsonReader.ReturnToBookmark(bookmark); bsonReader.ReadStartDocument(); bsonReader.FindElement("Name"); var stringType = BsonValue.ReadFrom(bsonReader).AsString; type = type.MakeGenericType(Type.GetType(stringType)); } else if (discriminator == "Setting") { type = typeof(Setting); } } catch (Exception ex) { type = typeof(Setting); } } bsonReader.ReturnToBookmark(bookmark); return(type); } } return(nominalType); }
public Type GetActualType(BsonReader bsonReader, Type nominalType) { BsonReaderBookmark bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); Type actualType = nominalType; if (bsonReader.FindElement("Type")) { BsonValue discriminator = BsonSerializer.Deserialize <BsonValue>(bsonReader); actualType = BsonSerializer.LookupActualType(nominalType, discriminator); } bsonReader.ReturnToBookmark(bookmark); return(actualType); }
public Type GetActualType(BsonReader bsonReader, Type nominalType) { var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); var actualType = nominalType; if (bsonReader.FindElement(ElementName)) { var discriminator = (BsonValue)BsonValueSerializer.Instance.Deserialize(bsonReader, typeof(BsonValue), null); actualType = BsonSerializer.LookupActualType(nominalType, discriminator); } bsonReader.ReturnToBookmark(bookmark); return(actualType); }
private Type GetActualType(BsonReader bsonReader) { var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); if (bsonReader.FindElement("type")) { var type = bsonReader.ReadString(); bsonReader.ReturnToBookmark(bookmark); switch (type) { case "Feature": return(typeof(GeoJsonFeature <TCoordinates>)); case "FeatureCollection": return(typeof(GeoJsonFeatureCollection <TCoordinates>)); case "GeometryCollection": return(typeof(GeoJsonGeometryCollection <TCoordinates>)); case "LineString": return(typeof(GeoJsonLineString <TCoordinates>)); case "MultiLineString": return(typeof(GeoJsonMultiLineString <TCoordinates>)); case "MultiPoint": return(typeof(GeoJsonMultiPoint <TCoordinates>)); case "MultiPolygon": return(typeof(GeoJsonMultiPolygon <TCoordinates>)); case "Point": return(typeof(GeoJsonPoint <TCoordinates>)); case "Polygon": return(typeof(GeoJsonPolygon <TCoordinates>)); default: var message = string.Format("The type field of the GeoJosnGeometry is not valid: '{0}'.", type); throw new FormatException(message); } } else { throw new FormatException("GeoJson object is missing the type field."); } }
// public methods /// <summary> /// Gets the actual type of an object by reading the discriminator from a BsonReader. /// </summary> /// <param name="bsonReader">The reader.</param> /// <param name="nominalType">The nominal type.</param> /// <returns>The actual type.</returns> public Type GetActualType(BsonReader bsonReader, Type nominalType) { // the BsonReader is sitting at the value whose actual type needs to be found var bsonType = bsonReader.GetCurrentBsonType(); if (bsonReader.State == BsonReaderState.Value) { Type primitiveType = null; switch (bsonType) { case BsonType.Boolean: primitiveType = typeof(bool); break; case BsonType.Binary: var bookmark = bsonReader.GetBookmark(); var binaryData = bsonReader.ReadBinaryData(); var subType = binaryData.SubType; if (subType == BsonBinarySubType.UuidStandard || subType == BsonBinarySubType.UuidLegacy) { primitiveType = typeof(Guid); } bsonReader.ReturnToBookmark(bookmark); break; case BsonType.DateTime: primitiveType = typeof(DateTime); break; case BsonType.Double: primitiveType = typeof(double); break; case BsonType.Int32: primitiveType = typeof(int); break; case BsonType.Int64: primitiveType = typeof(long); break; case BsonType.ObjectId: primitiveType = typeof(ObjectId); break; case BsonType.String: primitiveType = typeof(string); break; } // Type.IsAssignableFrom is extremely expensive, always perform a direct type check before calling Type.IsAssignableFrom if (primitiveType != null && (primitiveType == nominalType || nominalType.IsAssignableFrom(primitiveType))) { return(primitiveType); } } if (bsonType == BsonType.Document) { // ensure KnownTypes of nominalType are registered (so IsTypeDiscriminated returns correct answer) BsonSerializer.EnsureKnownTypesAreRegistered(nominalType); // we can skip looking for a discriminator if nominalType has no discriminated sub types if (BsonSerializer.IsTypeDiscriminated(nominalType)) { var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); var actualType = nominalType; if (bsonReader.FindElement(_elementName)) { var discriminator = (BsonValue)BsonValueSerializer.Instance.Deserialize(bsonReader, typeof(BsonValue), null); if (discriminator.IsBsonArray) { discriminator = discriminator.AsBsonArray.Last(); // last item is leaf class discriminator } actualType = BsonSerializer.LookupActualType(nominalType, discriminator); } bsonReader.ReturnToBookmark(bookmark); return(actualType); } } return(nominalType); }
/// <summary> /// Gets the actual type of an object by reading the discriminator from a BsonReader. /// </summary> /// <param name="bsonReader">The reader.</param> /// <param name="nominalType">The nominal type.</param> /// <returns>The actual type.</returns> public Type GetActualType( BsonReader bsonReader, Type nominalType ) { // the BsonReader is sitting at the value whose actual type needs to be found var bsonType = bsonReader.CurrentBsonType; if (bsonReader.State == BsonReaderState.Value) { Type primitiveType = null; switch (bsonType) { case BsonType.Boolean: primitiveType = typeof(bool); break; case BsonType.Binary: var bookmark = bsonReader.GetBookmark(); byte[] bytes; BsonBinarySubType subType; bsonReader.ReadBinaryData(out bytes, out subType); if (subType == BsonBinarySubType.Uuid && bytes.Length == 16) { primitiveType = typeof(Guid); } bsonReader.ReturnToBookmark(bookmark); break; case BsonType.DateTime: primitiveType = typeof(DateTime); break; case BsonType.Double: primitiveType = typeof(double); break; case BsonType.Int32: primitiveType = typeof(int); break; case BsonType.Int64: primitiveType = typeof(long); break; case BsonType.ObjectId: primitiveType = typeof(ObjectId); break; case BsonType.String: primitiveType = typeof(string); break; } if (primitiveType != null && nominalType.IsAssignableFrom(primitiveType)) { return(primitiveType); } } if (bsonType == BsonType.Document) { var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); var actualType = nominalType; if (bsonReader.FindElement(elementName)) { var discriminator = BsonValue.ReadFrom(bsonReader); if (discriminator.IsBsonArray) { discriminator = discriminator.AsBsonArray.Last(); // last item is leaf class discriminator } actualType = BsonDefaultSerializer.LookupActualType(nominalType, discriminator); } bsonReader.ReturnToBookmark(bookmark); return(actualType); } return(nominalType); }
public override object Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options) { var bsonType = bsonReader.CurrentBsonType; if (bsonType == BsonType.Null) { bsonReader.ReadNull(); return(null); } else if (bsonType == BsonType.Document) { var os = new ObjectSerializer(); MongoDynamic md = new MongoDynamic(); bsonReader.ReadStartDocument(); Dictionary <string, Type> typeMap = null; // scan document first to find interfaces { var bookMark = bsonReader.GetBookmark(); if (bsonReader.FindElement(MongoDynamic.InterfacesField)) { md[MongoDynamic.InterfacesField] = BsonSerializer.Deserialize <BsonValue>(bsonReader).AsBsonArray.Select(x => x.AsString); typeMap = md.GetTypeMap(); } else { throw new FormatException("No interfaces defined for this dynamic object - can't deserialize it"); } bsonReader.ReturnToBookmark(bookMark); } while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) { var name = bsonReader.ReadName(); if (name == "_id") { //md[name] = BsonValue.ReadFrom(bsonReader).AsObjectId; md[name] = BsonSerializer.Deserialize <ObjectId>(bsonReader); } else if (name == MongoDynamic.InterfacesField) { // Read it and ignore it, we already have it //BsonValue.ReadFrom(bsonReader); BsonSerializer.Deserialize <ObjectId>(bsonReader); } else { if (typeMap == null) { throw new FormatException("No interfaces define for this dynamic object - can't deserialize"); } // lookup the type for this element according to the interfaces Type elementType; if (typeMap.TryGetValue(name, out elementType)) { var value = BsonSerializer.Deserialize(bsonReader, elementType); md[name] = value; } else { // This is a value that is no longer in the interface, maybe a column you removed // not really much we can do with it ... but we need to read it and move on var value = BsonSerializer.Deserialize(bsonReader, typeof(object)); md[name] = value; // As with all databases, removing elements from the schema is always going to cause problems ... } } } bsonReader.ReadEndDocument(); return(md); } else { var message = string.Format("Can't deserialize a {0} from BsonType {1}.", nominalType.FullName, bsonType); throw new FormatException(message); } }
// public methods /// <summary> /// Gets the actual type of an object by reading the discriminator from a BsonReader. /// </summary> /// <param name="bsonReader">The reader.</param> /// <param name="nominalType">The nominal type.</param> /// <returns>The actual type.</returns> public Type GetActualType(BsonReader bsonReader, Type nominalType) { // the BsonReader is sitting at the value whose actual type needs to be found var bsonType = bsonReader.GetCurrentBsonType(); if (bsonReader.State == BsonReaderState.Value) { Type primitiveType = null; switch (bsonType) { case BsonType.Boolean: primitiveType = typeof(bool); break; case BsonType.Binary: var bookmark = bsonReader.GetBookmark(); byte[] bytes; BsonBinarySubType subType; bsonReader.ReadBinaryData(out bytes, out subType); if (subType == BsonBinarySubType.UuidStandard || subType == BsonBinarySubType.UuidLegacy) { primitiveType = typeof(Guid); } bsonReader.ReturnToBookmark(bookmark); break; case BsonType.DateTime: primitiveType = typeof(DateTime); break; case BsonType.Double: primitiveType = typeof(double); break; case BsonType.Int32: primitiveType = typeof(int); break; case BsonType.Int64: primitiveType = typeof(long); break; case BsonType.ObjectId: primitiveType = typeof(ObjectId); break; case BsonType.String: primitiveType = typeof(string); break; } // Type.IsAssignableFrom is extremely expensive, always perform a direct type check before calling Type.IsAssignableFrom if (primitiveType != null && (primitiveType == nominalType || nominalType.IsAssignableFrom(primitiveType))) { return primitiveType; } } if (bsonType == BsonType.Document) { // ensure KnownTypes of nominalType are registered (so IsTypeDiscriminated returns correct answer) BsonSerializer.EnsureKnownTypesAreRegistered(nominalType); // we can skip looking for a discriminator if nominalType has no discriminated sub types if (BsonSerializer.IsTypeDiscriminated(nominalType)) { var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); var actualType = nominalType; if (bsonReader.FindElement(_elementName)) { var discriminator = BsonValue.ReadFrom(bsonReader); if (discriminator.IsBsonArray) { discriminator = discriminator.AsBsonArray.Last(); // last item is leaf class discriminator } actualType = BsonSerializer.LookupActualType(nominalType, discriminator); } bsonReader.ReturnToBookmark(bookmark); return actualType; } } return nominalType; }