Reputation: 151
I am trying to set up an ASP.NET API with MongoDb as my database, and I'm currently trying to insert JSON objects into my database. But for some reason I just can't set a custom ID for my database.
If I let MongoDb automatically generate an ID, there is no issue, I can simply put JSON objects into the database:
{"_id":"5db0b2cf6abcc72fa42c8991","id":"pand3d.8575483","type":"Feature","geometry":{"type":"Polygon","coordinates":[[[108665.593,447232.925,0],[108667.648,447229.102,0],[108676.807,447234.217,0],[108674.334,447238.579,0],[108665.593,447232.925,0]]]},"geometry_name":"geovlak","properties":{"gid":8575483,"identificatie":"0513100011121832","aanduidingrecordinactief":false,"aanduidingrecordcorrectie":0,"officieel":false,"inonderzoek":false,"documentnummer":"BAGAV1776","documentdatum":"2018-08-15Z","bouwjaar":"1900-01-01Z","begindatumtijdvakgeldigheid":"2018-08-14T22:00:00Z","einddatumtijdvakgeldigheid":null,"gemeentecode":"0513","ground-000":"-0.44","ground-010":"-0.42","ground-020":"-0.41","ground-030":"-0.41","ground-040":"-0.4","ground-050":"-0.39","roof-025":"2.72","roof-050":"2.81","roof-075":"3.03","roof-090":"4.76","roof-095":"7.04","roof-099":"9.72","rmse-025":"0.87","rmse-050":"0.62","rmse-075":"0.62","rmse-090":"0.62","rmse-095":"0.62","rmse-099":"0.62","roof_flat":false,"nr_ground_pts":12,"nr_roof_pts":1247,"ahn_file_date":"2014-02-25T23:00:00Z","ahn_version":3,"height_valid":true,"tile_id":"38an2","bbox":["108665.593","447229.102","108676.807","447238.579"]}}
But as you can see, it generates a {"_id":"5db0b2cf6abcc72fa42c8991"} as the ID. But I want the {"id": "pand3d.8575483"} to act as ID.
So I made this Model:
public class Bag3DMember
{
[BsonId]
[DataMember]
[BsonElement("id")]
public string Id { get; set; }
[DataMember]
[BsonElement("type")]
public string Type { get; set; }
[BsonElement("geometry")]
public Geometry Geometry { get; set; }
[BsonElement("geometry_name")]
public string GeometryName { get; set; }
[BsonElement("properties")]
public Properties Properties { get; set; }
}
But when I insert the JSON objects into the database, I get this error message:
System.FormatException: 'Element 'id' does not match any field or property of class EnveoApi.Bag3DMember.'
Edit 1:
So I changes my Model to:
public class Bag3DMember
{
[BsonId]
[DataMember]
[BsonElement("_id")]
public string _Id { get; set; }
[DataMember]
[BsonElement("type")]
public string Type { get; set; }
[BsonElement("geometry")]
public Geometry Geometry { get; set; }
[BsonElement("geometry_name")]
public string GeometryName { get; set; }
[BsonElement("properties")]
public Properties Properties { get; set; }
}
But still got the same error, with this stacktrace:
at MongoDB.Bson.Serialization.BsonClassMapSerializer`1.DeserializeClass(BsonDeserializationContext context)
at MongoDB.Bson.Serialization.BsonClassMapSerializer1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer
1 serializer, BsonDeserializationContext context)
at MongoDB.Bson.Serialization.Serializers.EnumerableSerializerBase2.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer
1 serializer, BsonDeserializationContext context)
at MongoDB.Bson.Serialization.Serializers.ImpliedImplementationInterfaceSerializer2.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer
1 serializer, BsonDeserializationContext context)
at MongoDB.Bson.Serialization.BsonSerializer.Deserialize[TNominalType](IBsonReader bsonReader, Action1 configurator)
at MongoDB.Bson.Serialization.BsonSerializer.Deserialize[TNominalType](String json, Action
1 configurator)
at EnveoApi.Services.Bag3DService.SetupTestData() in D:\GitRepo\EnveoApi\Services\Bag3DService.cs:line 42
at EnveoApi.Services.Bag3DService..ctor(IBag3DMemberDatabaseSettings settings) in D:\GitRepo\EnveoApi\Services\Bag3DService.cs:line 32
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor
2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass4_0.b__0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.g__CreateController|0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
Upvotes: 1
Views: 534
Reputation: 151
So I think I have a solution.
Thanks to barrypicker pointing out that my application was having difficulty deserialization instead of serialization, I figured it might be because:
Here, my JSON id property doesn't match my Model (with serialization)
[BsonId]
[DataMember]
[BsonElement("_id")]
public string _Id { get; set; }
But here, my id JSON property does match my model. But when MongoDb inserts it, it renames the ID to _id, which means my Model also doesn't match (with Deserializiation)
[BsonId]
[DataMember]
[BsonElement("id")]
public string Id { get; set; }
So tldr: I wrote a function that changes the JSON key "id" to "_id" before inserting. Thanks barrypicker!
Upvotes: 1
Reputation: 10088
Please try the following and reply...
public class Bag3DMember
{
[BsonId]
[DataMember]
[BsonElement("_id")]
public string _Id { get; set; }
[DataMember]
[BsonElement("type")]
public string Type { get; set; }
[BsonElement("geometry")]
public Geometry Geometry { get; set; }
[BsonElement("geometry_name")]
public string GeometryName { get; set; }
[BsonElement("properties")]
public Properties Properties { get; set; }
}
In your code, change references to Bag3DMember.id
to Bag3DMember._id
Upvotes: 0