My mongodb user collection is of following schema:
{
_id: ObjectId("6420eb68cd0df40a33b0ead7"),
FirstName: 'Ashutosh',
LastName: 'Garg',
Email: '[email protected]',
Password: 'password',
Role: 'Tenant',
Properties: [
ObjectId("6420eeb8cd0df40a33b0eadb")
]
}
My User.cs is:
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
using System.Text.Json.Serialization;
namespace webapi.Models
{
public class User
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public String? Id { get; set; }
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string Role { get; set; }
public List<ObjectId>? Properties { get; set; }
}
}
This is my Login Service:
using Microsoft.Extensions.Options;
using MongoDB.Driver;
using webapi.Models;
namespace webapi.Services
{
public class LoginService
{
private readonly IMongoCollection<User> _userCollection;
public LoginService(IOptions<PropertyManagementDatabaseSettings> propertyManagementDatabaseSettings)
{
var mongoClient = new MongoClient(propertyManagementDatabaseSettings.Value.ConnectionString);
var mongoDatabase = mongoClient.GetDatabase(propertyManagementDatabaseSettings.Value.DatabaseName);
_userCollection = mongoDatabase.GetCollection<User>(propertyManagementDatabaseSettings.Value.UserCollectionName);
}
public async Task<User?> LoginAsync(string Email, string Password) =>
await _userCollection.Find(x => x.Email == Email && x.Password == Password).FirstOrDefaultAsync();
public async Task RegisterAsync(User newUser) =>
await _userCollection.InsertOneAsync(newUser);
}
}
This is my Login Controller:
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using webapi.Services;
using webapi.Models;
namespace webapi.Controllers
{
[ApiController]
[Route("[controller]")]
public class LoginController : ControllerBase
{
private readonly LoginService _loginService;
public LoginController(LoginService loginService)
{
_loginService = loginService;
}
[EnableCors("Policy1")]
[HttpGet("{Email}/{Password}")]
public async Task<ActionResult<User>> Get(string Email, string Password)
{
var user = await _loginService.LoginAsync(Email, Password);
if (user == null) { return NotFound(); }
return user;
}
[EnableCors("Policy1")]
[HttpPost]
public async Task<IActionResult> Post(User newUser)
{
await _loginService.RegisterAsync(newUser);
return CreatedAtAction(nameof(Get), new { id = newUser.Id }, newUser);
}
}
}
When I try to login using Swagger with email as [email protected] and password as password, I get the following response body:
{
"Id":"6420eb68cd0df40a33b0ead7",
"FirstName":"Ashutosh",
"LastName":"Garg",
"Email":"[email protected]",
"Password":"password",
"Role":"Tenant",
"Properties":[
{
"Timestamp":1679879864,
"Machine":13438452,
"Pid":2611,
"Increment":11594459,
"CreationTime":"2023-03-27T01:17:44Z"
}
]
}
But I want to get it in the following format
{
Id: ObjectId("6420eb68cd0df40a33b0ead7"),
FirstName: 'Ashutosh',
LastName: 'Garg',
Email: '[email protected]',
Password: 'password',
Role: 'Tenant',
Properties: [
ObjectId("6420eeb8cd0df40a33b0eadb")
]
}
What am I doing wrong? What should I try?
I have tried renaming the Properties field, I have also tried changing the datatype to string[] but it gives rise to –
System.FormatException: An error occurred while deserializing the RelatedProperties property of class webapi.Models.User: Cannot deserialize a ‘String’ from BsonType ‘ObjectId’.
—> System.FormatException: Cannot deserialize a ‘String’ from BsonType ‘ObjectId’.
2
Answers
The mongo driver know how to serialize/deserialize the ObjectId type but your json serializer doesn’t.
You need to write a custom converter for newtonsoft (or for System.Text.Serialization, depending what you use) and specify how to convert the mongo ObjectId type to string.
Here is the documentation from microsoft : https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/converters-how-to?pivots=dotnet-7-0
To use mongodb ObjectId you have to handle the HTTP stream yourself.
This is quite simple
More examples
https://github.com/iso8859/learn-mongodb-by-example/blob/main/dotnet/01%20-%20Begin/03%20-%20Serialization.cs