1
votes

When I try to do a simple find (unless its a find all of _context.People.Find(person => true).ToListAsync();) I get the returned error below. I have tried several iterations of filtering for the search and tried different fields with no success. Writing objects are fine but when I try to find off a specific field I run into errors. It fails on the repo in debug. Doesn't get to the var id = person.PersonId line.

This error is the same wether its local db or cosmosdb

Returned Error

System.Text.Json.JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_SerializerCycleDetected(Int32 maxDepth) at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state) at System.Text.Json.JsonSerializer.WriteAsyncCore(Stream utf8Json, Object value, Type inputType, JsonSerializerOptions options, CancellationToken cancellationToken) at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding) at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
     services.Configure<Settings>(
                options =>
                {
                    
                    options.ConnectionString =
                        Configuration.GetSection("MongoDb:ConnectionString").Value;
                    
                    options.Database = Configuration.GetSection("MongoDb:Database").Value;
                });

            services.AddSingleton<IMongoClient, MongoClient>(
            _ => new MongoClient(Configuration.GetSection("MongoDb:ConnectionString").Value));
            ...
            services.AddSingleton<IMyDbContext, MyDbContext>();
            services.AddSingleton<IPersonRepository, PersonRepository>();

Settings.cs

public class Settings
    {
        public string ConnectionString { get; set; }
        public string Database { get; set; }
    }

MyDbContext.cs

public class MyDbContext : IMyDbContext

    {
        private readonly IMongoDatabase _db;

        public MyDbContext(IOptions<Settings> options, IMongoClient client)
        {
            _db = client.GetDatabase(options.Value.Database);
        }

        public IMongoCollection<Person> People => _db.GetCollection<Person>("People");
     }

appsettings.json

{
  "MongoDB": {
    "ConnectionString": "mongodb://host.docker.internal:27017",
    "Database": "Gobiez"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

Person.cs

public class Person
    {
        [BsonId]
        public ObjectId Id { get; set; }
        public Guid PersonId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public string Address { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }
        public string PhoneNumber { get; set; }
    }

PersonRepository

public class PersonRepository : IPersonRepository
    {
        private readonly IGobiezContext _context;

        public PersonRepository(IGobiezContext gobiezContext)
        {
            _context = gobiezContext;
        }
        **// This one works**
        public async Task<IEnumerable<Person>> GetAllPeople()
        {
            return await _context.People.Find(person => true).ToListAsync(); ;
        }
        **// This one fails with the top error**
        public async Task<Guid> GetPersonIdByLastName(string personString)
        {
            FilterDefinition<Person> filter = Builders<Person>.Filter.Eq(p => p.LastName, personString);
   ******   var person = await _context.People.Find(filter).FirstAsync();  //Fails here ******      
            var id = person.PersonId;  
            return id;
        }
    }

PersonController

    [Route("api/[controller]")]
    [ApiController]
    public class PersonController : ControllerBase
    {
        private readonly IPersonRepository personRepository;
 
        public PersonController(IPersonRepository personRepository)
        {
            this.personRepository = personRepository;

        }

        [HttpPost]
        [Authorize]
        public IActionResult CreatePerson(NewPerson newPerson)
        {
            var person = new Person()
            {
                FirstName = newPerson.FirstName,
                LastName = newPerson.LastName,
                Email = newPerson.Email,
                Address = newPerson.Address,
                State = newPerson.State,
                ZipCode = newPerson.ZipCode,
                PhoneNumber = newPerson.PhoneNumber
            };
            

            person.PersonId = Guid.NewGuid();

            try
            {
                personRepository.CreatePerson(person);
            }
            catch (Exception e)
            {
                return BadRequest($"Something went bad...{e.Message}");
               
            }

            return Ok(person);

        }
        
        [HttpGet]
        public async Task<IActionResult> GetAllPeople()
        {
            var result = await personRepository.GetAllPeople();

            return Ok(result);
        }

       [HttpGet("last/{last}")]
        public async Task<IActionResult> GetPersonByLastName(string last)
        {
            try
            {
                var person = await personRepository.GetPersonByLastName(last);
                return Ok(person);
            }
            catch (Exception e)
            {

                return BadRequest(e);
            }      
           
        }

New error after ignore loops addition suggested by EVK

 "ClassName": "System.ArgumentNullException",
    "Message": "Value cannot be null.",
    "Data": null,
    "InnerException": null,
    "HelpURL": null,
    "StackTraceString": "   at MongoDB.Driver.Core.Misc.Ensure.IsNotNull[T](T value, String paramName)\n   at MongoDB.Driver.FindFluent`2..ctor(IClientSessionHandle session, IMongoCollection`1 collection, FilterDefinition`1 filter, FindOptions`2 options)\n   at MongoDB.Driver.IMongoCollectionExtensions.FindHelper[TDocument](IClientSessionHandle session, IMongoCollection`1 collection, FilterDefinition`1 filter, FindOptions options)\n   at MongoDB.Driver.IMongoCollectionExtensions.Find[TDocument](IMongoCollection`1 collection, FilterDefinition`1 filter, FindOptions options)\n   at App.API.Business.Repository.PersonRepository.GetPersonByLastName(String lastName) in C:\\Users\\pstal\\Desktop\\App.API.Business\\App.Business.Backend\\App.API.Business\\Repository\\PersonRepository.cs:line 64\n   at App.API.Business.Controllers.BusinessController.GetPersonByLastName(String last) in C:\\Users\\pstal\\Desktop\\App.API.Business\\App.Business.Backend\\App.API.Business\\Controllers\\BusinessController.cs:line 168",
    "RemoteStackTraceString": null,
    "RemoteStackIndex": 0,
    "ExceptionMethod": null,
    "HResult": -2147467261,
    "Source": "MongoDB.Driver.Core",
    "WatsonBuckets": null,
    "ParamName": "collection"
}

1
It fails when sending response, but code above does not show controller action on which it fails - Evk
It’s just a very simple call to the repository. The repository comes up null and fails the controller. The error above is from a try catch that I set at the repo call. It doesn’t even make it to the var id line in the getpersonid function - Ramious

1 Answers

0
votes

Looks like you need to install Microsoft.AspNetCore.Mvc.NewtonsoftJson package and configure the services:

services.AddControllers().AddNewtonsoftJson(options =>
    options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);