如何根据请求设置JsonSerializerOption

huangapple go评论69阅读模式
英文:

How to set JsonSerializerOption per request

问题

我有一个.NET 7的Web API,其中有一个路由返回用户。

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

如果"Name"出现在Select查询参数中,数据库只返回Name属性,然后Ok(users);返回。例如:

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

为了减小包大小,我想要返回:

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

但是,如果在Select查询参数中什么都没有,所有属性都会被填充并返回,即使是null/默认值。如何动态设置JsonSerializerOptions,以便如果设置了SelectOk(users)在序列化时忽略null/默认属性,否则返回所有属性?

英文:

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?

答案1

得分: 1

以下是翻译好的部分:

"IMHO the simpliest way is" 翻译成中文:在我看来,最简单的方法是

"if (users[0].Id != null) return Ok(users); //or more validations" 翻译成中文:如果 (users[0].Id != null) 返回 Ok(users); // 或更多的验证

"return Ok( users.Select(u => new { Name = u.Name }) );" 翻译成中文:返回 Ok( users.Select(u => new { Name = u.Name }) );

英文:

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 }) );
		

答案2

得分: 0

我不确定这是否是最佳方式,但利用匿名类型是一个启发。我认为我需要动态地和递归地找到Select中的所有属性,然后将其添加到匿名类型中。与其重新发明轮子,为什么不直接使用System.Text.Json呢?

if (select不为空 && select.Count > 0)
{
var modelsWithLessProperties = JsonSerializer.Deserialize(JsonSerializer.Serialize(models, new JsonSerializerOptions
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
}));

return Ok(modelsWithLessProperties);

}

return Ok(models);

序列化然后反序列化可能不是最有效的方法,但它利用了已经建立的代码。

我愿意尝试任何更高效、已建立(即不容易出错)的方法来做这个事情。

英文:

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.

huangapple
  • 本文由 发表于 2023年2月8日 09:42:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75380632.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定

  • 开发者交流平台

    本页二维码