.NET Core 2.2+MongoDB用户管理API及JSON转Bson文档问题咨询
Hey there! Let's tackle your two questions one by one, with practical code examples tailored to your .NET Core 2.2 and MongoDB setup.
If you're using the official MongoDB .NET Driver, this is straightforward with the built-in serialization tools. Here's how to do it:
- First, make sure you have the
MongoDB.DriverNuGet package installed (it's a must for your project anyway). - Use
BsonSerializer.Deserializeto convert the JSON string directly into a list ofBsonDocument:
using MongoDB.Bson; using MongoDB.Bson.Serialization; // Example JSON string with multiple user objects string jsonUsers = @"[ {""id"": 1, ""name"": ""Leanne Graham"", ""username"": ""Bret""}, {""id"": 2, ""name"": ""Ervin Howell"", ""username"": ""Antonette""} ]"; // Convert to BsonDocument array List<BsonDocument> bsonDocuments = BsonSerializer.Deserialize<List<BsonDocument>>(jsonUsers);
If you prefer working with strongly-typed classes instead of BsonDocument, define a User class matching the JSON structure, then deserialize to List<User>—the driver will handle converting it to Bson automatically when inserting into MongoDB.
For your user management project, here's a step-by-step solution to load data from the external API and batch insert it into MongoDB when your .NET Core 2.2 API starts:
Step 1: Define the User Entity Class
Create a strongly-typed class that maps to the external API's JSON structure. This makes deserialization and MongoDB operations cleaner:
using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; public class User { [BsonId] [BsonRepresentation(BsonType.ObjectId)] public string Id { get; set; } // MongoDB's default ObjectId [BsonElement("id")] public int ExternalId { get; set; } // ID from the external API public string Name { get; set; } public string Username { get; set; } public Address Address { get; set; } public Company Company { get; set; } // Add other properties matching the external API's JSON fields } public class Address { public string Zipcode { get; set; } // Include other address properties like street, city, etc. } public class Company { public string Name { get; set; } // Include other company properties like catchPhrase, bs, etc. }
Step 2: Register MongoDB Services in Startup.cs
Configure the MongoDB client and collection in Startup.cs so you can inject them into other services:
using MongoDB.Driver; public void ConfigureServices(IServiceCollection services) { // Register MongoDB client with your connection string services.AddSingleton<IMongoClient>(sp => new MongoClient(Configuration.GetConnectionString("MongoDB"))); // Register the Users collection services.AddSingleton<IMongoCollection<User>>(sp => sp.GetRequiredService<IMongoClient>().GetDatabase("YourDatabaseName").GetCollection<User>("Users")); // Add MVC, Swagger, Authentication services services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); // ... Add Swagger setup and authentication config here }
Step 3: Create a Hosted Service for Startup Data Import
Use an IHostedService to run the import when the API starts (this is the recommended way for background startup tasks in .NET Core):
using System; using System.Collections.Generic; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Hosting; using MongoDB.Driver; using Newtonsoft.Json; // .NET Core 2.2 uses Newtonsoft.Json by default public class UserDataImporterHostedService : IHostedService { private readonly IMongoCollection<User> _usersCollection; private readonly IHttpClientFactory _httpClientFactory; public UserDataImporterHostedService(IMongoCollection<User> usersCollection, IHttpClientFactory httpClientFactory) { _usersCollection = usersCollection; _httpClientFactory = httpClientFactory; } public async Task StartAsync(CancellationToken cancellationToken) { try { // Skip import if data already exists to avoid duplicates var existingCount = await _usersCollection.CountDocumentsAsync(_ => true, cancellationToken: cancellationToken); if (existingCount > 0) { Console.WriteLine("User data already exists, skipping import."); return; } // Fetch data from external API var httpClient = _httpClientFactory.CreateClient(); var jsonResponse = await httpClient.GetStringAsync("https://jsonplaceholder.typicode.com/users", cancellationToken); var users = JsonConvert.DeserializeObject<List<User>>(jsonResponse); // Batch insert into MongoDB await _usersCollection.InsertManyAsync(users, cancellationToken: cancellationToken); Console.WriteLine($"Successfully imported {users.Count} users into MongoDB."); } catch (Exception ex) { Console.WriteLine($"Error importing user data: {ex.Message}"); // Replace Console with ILogger in production for proper logging } } public Task StopAsync(CancellationToken cancellationToken) { return Task.CompletedTask; } }
Register this hosted service in Startup.cs:
public void ConfigureServices(IServiceCollection services) { // ... Existing MongoDB and other services // Register the data importer service services.AddHostedService<UserDataImporterHostedService>(); // Add HttpClientFactory for API calls services.AddHttpClient(); }
Quick Tips for Your Full Project:
- Authentication: Implement header-based username/password auth with a custom
AuthorizationHandleror basic auth middleware, and apply it to all API endpoints. - Swagger: Configure Swagger to include the authentication header so you can test endpoints directly in the Swagger UI.
- CRUD & Search: Inject
IMongoCollection<User>into your controller, then use methods likeInsertOneAsync,ReplaceOneAsync,DeleteOneAsync, andFindAsyncwith filtered queries for multi-condition search (match name, username, zipcode, or company name). - Data Refresh: If you need to periodically update user data, modify the hosted service to use
BulkWriteAsyncwith upsert operations instead of skipping existing data.
内容的提问来源于stack exchange,提问作者samehfrehat

