为列表中的某些特定项目提供附加信息
Supply additional information with some specific items in a list
假设我有一个 class,其中包含一个 属性,如下所示:
ListOfObjectA;
对象 A 定义如下:
Class ObjectA:
Prop a
Prop b
ListOfObjectA(return 由 API 端点编辑为 DTO)将在 UI 中呈现。
在某些情况下,列表中的特定 ObjectA 实例需要提供额外的支持信息(假设另一个对象 SubObjectA(复杂类型),这对列表中的其他项目不常见)即n+1 例。
我正在尝试了解 return 此信息的最佳方式,而不用不必要的信息阻塞 DTO。
一个选项是将 SubObjectx 包含在 ObjectA class 本身中 - 当它为 null 或空时,不要费心渲染它。我们会以编程方式在需要的地方填充它...
第二个选项可能是添加一个 url 属性 到 ObjectA class - url 可以是空的或指向一个端点以获取额外的信息和然后可以呈现响应。
我个人反对第一个选项,因为 ListOfObjectA 中的每个对象将始终包含不相关的信息。我更喜欢第二个选项,因为它包含一个字符串(端点),即如果具有从何处获取子对象的值。但这也意味着 API 的客户端现在可以对一些逻辑进行编程,以便在需要时访问这些端点。
我想知道是否有其他更好的方法来做到这一点?
如果我对情况的解释不是很好,请问我一个问题。
无论您是从请求主体对 JSON 进行自动模型绑定,还是手动使用 JsonConvert
之类的东西来创建模型,您的 DTO class(es) 都需要拥有所有可能的属性。没有真正的方法可以根据某些特定数据的存在与否从同一组数据实例化不同类型的对象。也就是说,您可以创建一个自定义模型绑定器和一些自定义 JSON 解析器来完成工作,但主要是装饰性的东西所涉及的工作量不值得投资。
就其价值而言,这只是 DTO classes 本身的问题。您可以利用 JSON.NET 中的东西,例如 JsonIgnore
属性和 NullValueHandling
和 DefaultValueHandling
枚举来隐藏实际 JSON 中的成员,如果这是您最关心的。例如:
public class ObjectA:
{
public string A { get; set; }
public string B { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string C { get; set; }
}
然后,当你序列化你的对象时,如果 C
属性 没有设置,你会得到 JSON 像:
{
"a" : "foo",
"b" : "bar"
}
如果已设置,您将获得:
{
"a" : "foo",
"b" : "bar",
"c" : "baz"
}
除此之外,我认为您最好的选择是在必要时请求额外数据的链接。这实际上是一件非常 REST 的事情。它本质上是 HATEOAS。然而,它也非常 喋喋不休 。这将需要提出更多请求,特别是如果您必须对多个项目执行此操作。它本质上是应用于 API.
的 N+1 数据库查询问题
您可以使用 List<anonymous_objects>
。
var DTO = new List
{
new {City = "Chicago", Code = "114"},
new {City="Washington"},
new {City="London", Code = "2"}
}
等等。但是有一个小问题:您需要使用反射从项目中获取数据:
var city = DTO[0].GetType().GetProperty(nameof(DTO[0].City)).GetValue(DTO[0]);
此外,我想(我没有检查)您可以使用 List<dynamic>
。都一样,但你会写 new List<dynamic>
并且你不需要使用 GetType 和所有这些东西。只写DTO[0].City
。试试这个:)
假设我有一个 class,其中包含一个 属性,如下所示:
ListOfObjectA;
对象 A 定义如下:
Class ObjectA:
Prop a
Prop b
ListOfObjectA(return 由 API 端点编辑为 DTO)将在 UI 中呈现。
在某些情况下,列表中的特定 ObjectA 实例需要提供额外的支持信息(假设另一个对象 SubObjectA(复杂类型),这对列表中的其他项目不常见)即n+1 例。
我正在尝试了解 return 此信息的最佳方式,而不用不必要的信息阻塞 DTO。
一个选项是将 SubObjectx 包含在 ObjectA class 本身中 - 当它为 null 或空时,不要费心渲染它。我们会以编程方式在需要的地方填充它...
第二个选项可能是添加一个 url 属性 到 ObjectA class - url 可以是空的或指向一个端点以获取额外的信息和然后可以呈现响应。
我个人反对第一个选项,因为 ListOfObjectA 中的每个对象将始终包含不相关的信息。我更喜欢第二个选项,因为它包含一个字符串(端点),即如果具有从何处获取子对象的值。但这也意味着 API 的客户端现在可以对一些逻辑进行编程,以便在需要时访问这些端点。
我想知道是否有其他更好的方法来做到这一点?
如果我对情况的解释不是很好,请问我一个问题。
无论您是从请求主体对 JSON 进行自动模型绑定,还是手动使用 JsonConvert
之类的东西来创建模型,您的 DTO class(es) 都需要拥有所有可能的属性。没有真正的方法可以根据某些特定数据的存在与否从同一组数据实例化不同类型的对象。也就是说,您可以创建一个自定义模型绑定器和一些自定义 JSON 解析器来完成工作,但主要是装饰性的东西所涉及的工作量不值得投资。
就其价值而言,这只是 DTO classes 本身的问题。您可以利用 JSON.NET 中的东西,例如 JsonIgnore
属性和 NullValueHandling
和 DefaultValueHandling
枚举来隐藏实际 JSON 中的成员,如果这是您最关心的。例如:
public class ObjectA:
{
public string A { get; set; }
public string B { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string C { get; set; }
}
然后,当你序列化你的对象时,如果 C
属性 没有设置,你会得到 JSON 像:
{
"a" : "foo",
"b" : "bar"
}
如果已设置,您将获得:
{
"a" : "foo",
"b" : "bar",
"c" : "baz"
}
除此之外,我认为您最好的选择是在必要时请求额外数据的链接。这实际上是一件非常 REST 的事情。它本质上是 HATEOAS。然而,它也非常 喋喋不休 。这将需要提出更多请求,特别是如果您必须对多个项目执行此操作。它本质上是应用于 API.
的 N+1 数据库查询问题您可以使用 List<anonymous_objects>
。
var DTO = new List
{
new {City = "Chicago", Code = "114"},
new {City="Washington"},
new {City="London", Code = "2"}
}
等等。但是有一个小问题:您需要使用反射从项目中获取数据:
var city = DTO[0].GetType().GetProperty(nameof(DTO[0].City)).GetValue(DTO[0]);
此外,我想(我没有检查)您可以使用 List<dynamic>
。都一样,但你会写 new List<dynamic>
并且你不需要使用 GetType 和所有这些东西。只写DTO[0].City
。试试这个:)