Mongo C# Driver og ObjectID JSON String Format i .NET Core

 C Programming >> C Programmering >  >> Tags >> .NET
Mongo C# Driver og ObjectID JSON String Format i .NET Core

Brug BsonDocument, når du gemmer i MongoDB

Efter at have prøvet en række forskellige konfigurationer, var den eneste måde, jeg var i stand til korrekt at gemme virkelig dynamiske dokumenter ved hjælp af connectoren, at parse objekter som BsonDocument s.

public ActionResult Post([FromBody]JObject resource)
{
    var document = BsonDocument.Parse(resource.ToString(Formatting.None));

    DbContext.Resources.InsertOne(document);
}

Tilmeld dig BsonDocument serializers med JSON.Net

Problemet med ovenstående tilgang var oprindeligt, at når du kalder ToJson() ISODate og ObjectId objekter ville blive serialiseret til objekter, hvilket var uønsket. I skrivende stund ser der ikke ud til at være nogen udvidelsesmuligheder for at tilsidesætte denne adfærd. Logikken er indbygget i MongoDB.Bson.IO.JsonWriter klasse, og du kan ikke registrere BsonSerializer s for BsonValue typer:

I skrivende stund er den eneste løsning, jeg har fundet, at eksplicit tilpassede JSON.Net-konvertere. MongoDB C# Lead Robert Stam har oprettet et upubliceret bibliotek til dette, som fællesskabsmedlem Nathan Robinson har overført til .net-core.. Jeg har lavet en fork, der korrekt serialiserer felterne ObjectId og ISODate.

Jeg har lavet en NuGet-pakke ud fra deres arbejde. For at bruge den skal du inkludere følgende reference i din .csproj fil:

<PackageReference Include="MongoDB.Integrations.JsonDotNet" Version="1.0.0" />

Registrer derefter eksplicit konverterne:

Startup.cs

using MongoDB.Integrations.JsonDotNet.Converters;

public class Startup
{
    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().AddJsonOptions(options =>
        {
            // Adds automatic json parsing to BsonDocuments.
            options.SerializerSettings.Converters.Add(new BsonArrayConverter());
            options.SerializerSettings.Converters.Add(new BsonMinKeyConverter());
            options.SerializerSettings.Converters.Add(new BsonBinaryDataConverter());
            options.SerializerSettings.Converters.Add(new BsonNullConverter());
            options.SerializerSettings.Converters.Add(new BsonBooleanConverter());
            options.SerializerSettings.Converters.Add(new BsonObjectIdConverter());
            options.SerializerSettings.Converters.Add(new BsonDateTimeConverter());
            options.SerializerSettings.Converters.Add(new BsonRegularExpressionConverter());
            options.SerializerSettings.Converters.Add(new BsonDocumentConverter());
            options.SerializerSettings.Converters.Add(new BsonStringConverter());
            options.SerializerSettings.Converters.Add(new BsonDoubleConverter());
            options.SerializerSettings.Converters.Add(new BsonSymbolConverter());
            options.SerializerSettings.Converters.Add(new BsonInt32Converter());
            options.SerializerSettings.Converters.Add(new BsonTimestampConverter());
            options.SerializerSettings.Converters.Add(new BsonInt64Converter());
            options.SerializerSettings.Converters.Add(new BsonUndefinedConverter());
            options.SerializerSettings.Converters.Add(new BsonJavaScriptConverter());
            options.SerializerSettings.Converters.Add(new BsonValueConverter());
            options.SerializerSettings.Converters.Add(new BsonJavaScriptWithScopeConverter());
            options.SerializerSettings.Converters.Add(new BsonMaxKeyConverter());
            options.SerializerSettings.Converters.Add(new ObjectIdConverter());
        }); 
    }
}

Nu kan du serialisere ved hjælp af standard serializer:

return Created($"resource/{document["_id"].ToString()}", document);

Du kan få dit sidste forsøg til at virke ved at registrere brugerdefineret ObjectIdConverter med NewtonSoft.

await resources = _database.GetCollection<dynamic>("resources")
    .Find(Builders<dynamic>.Filter.Empty)
    .ToListAsync();

return Ok(Newtonsoft.Json.JsonConvert.SerializeObject(resources, new ObjectIdConverter()));

Konverter:

class ObjectIdConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value.ToString());

    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override bool CanConvert(Type objectType)
    {
        return typeof(ObjectId).IsAssignableFrom(objectType);
    }
}

Bemærk:Ovenstående konverter konverterer fra ObjectId til streng efter BSONSerailzers har konverteret bson-værdi til ObjectId .

Du skal stadig bruge parse til at konvertere streng-id til ObjectId'er for forespørgsler og registrere ObjectIdConverter globalt.

Reference:https://stackoverflow.com/a/16693462/2683814