skip to Main Content

I have a .NET 7 web api with a route that returns Users.

public class User
{
    public Guid? Id { get; set; }
    public String? Name { get; set; }
    public Int32? Age { get; set; }
    public String? HairColor { get; set; }
}

If "Name" comes in the Select query param, the database only returns the Name property and the Ok(users); returns. Ex:

[
    {
        "id": null,
        "name": "Test1",
        "age": null,
        "hairColor": null
    },
    {
        "id": null,
        "name": "Test2",
        "age": null,
        "hairColor": null
    },
    {
        "id": null,
        "name": "Test3",
        "age": null,
        "hairColor": null,
    }
]

To save on package size, I would instead like it to return:

[
    {
        "name": "Test1"
    },
    {
        "name": "Test2"
    },
    {
        "name": "Test3"
    }
]

But, if nothing comes in the Select query param, all of the properties get populated and returned even if null/default. How can I dynamically set

JsonSerializerOptions options = new()
{
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
};

So that if Select is set, Ok(users) ignores the null/default properties when serializing, otherwise it returns all properties?

2

Answers


  1. Chosen as BEST ANSWER

    I'm not sure if this is the best way, but utilizing anonymous types was a spark. I thought, I would need to dynamically and recursively find all of the properties in Select, then add it to the anonymous type. Instead of reinventing the wheel, why not just utilize System.Text.Json?

    if (select is not null && select.Count > 0)
    {
        var modelsWithLessProperties = JsonSerializer.Deserialize<object>(JsonSerializer.Serialize(models, new JsonSerializerOptions
        {
            DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
        }));
    
        return Ok(modelsWithLessProperties);
    }
    
    return Ok(models);
    

    Serializing, then deserializing may not be the most efficient way of doing this, but it is utilizing established code.

    I am open to any, more efficient, established (i.e. not error prone) way of doing this.


  2. IMHO the simpliest way is

        if (users[0].Id != null) return Ok(users); //or more validations
        return Ok( users.Select(u => new { Name = u.Name }) );
            
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search