英文:
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
,以便如果设置了Select
,Ok(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
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论