Eli2099
Eli2099

Reputation: 97

Http request how to return a list of objects

So I have moved from working with Java to C# and man is Spring boot different from C#. I am trying to return a list of objects to a rest API using mongodb database. But the result does not return a list, but rather some object containing my list.

Brand class

[BsonIgnoreExtraElements]
public class Brand
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string _id { get; set; }
    public string name { get; set; }
}

Controller

[HttpGet("getAllBrands")]
public async Task<IActionResult> Get()
{
    var brands = await _brandRepository.getAllBrands();

    List<Brand> list = (List<Brand>) brands;

    return new JsonResult(list);
} 

Brand Repository

public async Task<IEnumerable<Brand>> getAllBrands()
{
    var brands = await _brands.Find(_ => true).ToListAsync();
    return brands;
}

What I expect

[
      {
        "_id": "60d235f60f8c98376ba5b67d",
        "name": "Some brand 1"
      },
      {
        "_id": "60d24d6b0f8c98376ba5b68c",
        "name": "Some brand 2"
      },
      {
        "$id": "6",
        "_id": "60d24e4b0f8c98376ba5b68d",
        "name": "Some brand 3"
      }
    ]

What I'm actually getting

{
  "$id": "1",
  "$values": [
    {
      "$id": "2",
      "_id": "60d235f60f8c98376ba5b67d",
      "name": "Some brand 1"
    },
    {
      "$id": "4",
      "_id": "60d24d6b0f8c98376ba5b68c",
      "name": "Some brand 2"
    },
    {
      "$id": "6",
      "_id": "60d24e4b0f8c98376ba5b68d",
      "name": "Some brand 1"
    }
  ]
}

How do I just return a simple list of objects as my result and not that? Thanks

Upvotes: 2

Views: 4065

Answers (2)

devNull
devNull

Reputation: 4219

The JSON you're seeing is expected when your JSON serializer is setup to preserve references. With this, metadata members ($id, $ref, $values) are added so that objects can be referenced within the JSON, instead of duplicated.

More specifically (see ReferenceHandler.Preserve):

For enumerable types, such as List, the JSON array must be nested within a JSON object containing an $id and $values metadata property, in that order

This is likely configured in your app startup, for example:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()
        .AddJsonOptions(options => 
           options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve);
}

To get your expected JSON, you'll need to disable this functionality. You can do this either in the app startup, as before:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()
        .AddJsonOptions(options => 
           options.JsonSerializerOptions.ReferenceHandler = null);
}

Or only for that specific endpoint:

[HttpGet("getAllBrands")]
public async Task<IActionResult> Get()
{
    var brands = await _brandRepository.getAllBrands();

    List<Brand> list = (List<Brand>) brands;

    return new JsonResult(list, new JsonSerializerOptions
    {
        ReferenceHandler = null,
        WriteIndented = true
    });
}

Upvotes: 5

In your Controller try this piece of code

public async Task<ActionResult<Brand>> Get()
{
    var brands = await _brandRepository.getAllBrands();

    List<Brand> list = (List<Brand>) brands;

    return Ok(list);
} 

If Ok() have an error just make sure that your Controller is inherited from BaseController

Upvotes: 0

Related Questions