C# 如何在具有新JSON字符串的类中重置JsonProperties
我已经将JSON反序列化为一个c#对象,但是JSON不完整,因此缺少一些属性。在反序列化对象时,我没有访问完整JSON的权限。我可以通过进行另一个API调用来获得完整的JSON,但如果不需要的话,我不想进行该调用 我希望我的属性获取程序能够工作,以便在属性不为null时返回该属性。如果为null,它应该调用API以获取完整的JSON并更新类中的所有JsonProperties,然后返回我请求的属性C# 如何在具有新JSON字符串的类中重置JsonProperties,c#,.net,json,json-deserialization,C#,.net,Json,Json Deserialization,我已经将JSON反序列化为一个c#对象,但是JSON不完整,因此缺少一些属性。在反序列化对象时,我没有访问完整JSON的权限。我可以通过进行另一个API调用来获得完整的JSON,但如果不需要的话,我不想进行该调用 我希望我的属性获取程序能够工作,以便在属性不为null时返回该属性。如果为null,它应该调用API以获取完整的JSON并更新类中的所有JsonProperties,然后返回我请求的属性 public class Car { private string _make;
public class Car
{
private string _make;
private string _model;
[JsonProperty("make")]
public string Make
{
get
{
if (_make != null)
{
return _make;
}
else
{
UpdateProperties();
return _make;
}
}
}
[JsonProperty("model")]
public string Model
{
get
{
if (_model != null)
{
return _model;
}
else
{
UpdateProperties();
return _model;
}
}
}
[JsonProperty("self")]
public Uri Self { get; set; }
public void UpdateProperties()
{
}
}
在上面的UpdateProperties()方法中,我可以让它使用Self属性获取并反序列化一个Car类的新实例,但我希望它刷新当前Car类实例的属性。我可以通过再次单独设置每个属性来手动执行此操作,但由于我需要为许多类执行此操作,因此我希望有更好的方法。这可能吗
还是我完全错了
编辑:
下面是API将返回的JSON示例。假设我打电话来获取车队的信息。它将返回:
{
"details" : "something"
"car": {
"make": "Ford",
"self": "https://..."
}
"truck": {
"age": 30,
"self": "https://..."
}
}
其中,当您访问car.self提供的url时,它将返回以下JSON:
{
"make" : "Toyota",
"model" : "Camry",
"self" : "https://..."
}
当前设置中手动重置所有属性的唯一方法 您希望这是自动的,这是正确的,因为这是大量的样板代码。这是一个常见问题,最常见的解决方案是使用
DTO
或数据传输对象模式
您将引入一个名为CarDto
的新类,而不是Car
公开私有字段,它将公开CarDto
上的属性
见下文:
public class Car {
private CarDto _dto = null;
public Car(CarDto dto = null) {
//If we pass in a dto, use it, otherwise create a new one
_dto = dto ?? new CarDto();
}
[JsonProperty("make")]
public string Make {
get {
if (_dto.Make == null) {
UpdateProperties();
}
return _dto.Make;
}
}
[JsonProperty("model")]
public string Model {
get {
if (_dto.Model == null) {
UpdateProperties();
}
return _dto.Model;
}
}
[JsonProperty("self")]
public Uri Self { get; set; }
public void UpdateProperties() {
//The API would return a CarDto.
CarDto newDto = APICall(); //Mock code
_dto = newDto;
}
}
public class CarDto {
public string Make { get;set; }
public string Model { get;set; }
}
现在,如果您有一个null属性,您将调用UpdateProperties
。然后,这将返回一个新的CarDto
,您将其用作您的私人\u dto
字段
这是一个非常有用且通用的模式,它使事情变得更加简单,因此使用它来实现和练习是非常棒的!如果有什么不清楚的地方,请告诉我。因此,让我提供一个不同的视角。问题描述似乎很简单——我有两个API调用,一个返回部分对象,另一个返回完整对象。如果不需要的话,我不想打两个电话。所以,如果需要的话,我会打第二个电话“填写细节”,对吗 错 提议的方法不是一个好主意。 这从API的设计开始就偏离了轨道。API返回的对象不应该太复杂,以至于需要多次调用才能返回代码中描述的“完整”对象。但是,让我们假设我无法控制API的设计-我应该怎么做 程序员经常面临着面对设计糟糕的API的任务。这些问题就像本问题中描述的那样,人们强烈希望“掩盖”糟糕的API设计。问题是并非所有糟糕的设计都可以掩盖。这是一个 这里提出的是引入
get
访问器的痛苦副作用。这可以说是解决糟糕的API设计问题的最糟糕的方法。典型的get
方法返回的时间可以忽略不计——这是一个简单的内存访问。这个建议的get
访问器可能需要几秒钟才能返回,可能会失败,可能会引发异常。更糟糕的是,调用方没有任何迹象表明这实际上是对外部接口的访问。最终,对象的状态是不确定的,这可能是程序中最糟糕的情况
如果这还不够糟糕的话,get
访问器没有提供异步操作,这在处理远程API时很常见。用户体验将受到影响。通过采用这种方法,我将实际解决一个问题,并在使用该类的任何地方提出一个新问题
更好的方法:
API有两个独立的函数,因此实际上,这意味着两个独立的结果类型。我将为部分类创建一个类型,为完整类创建第二个类型。毕竟,我在写代码——除非代码习惯于自己重写,否则在写代码的时候,我应该知道我需要的是对象的完整表示还是部分表示
为了获得完整的表示,我将提供对API的单独访问,并提供允许异步执行的适当方法(例如,可观察)。这将有额外的好处,允许我检查(通过“where used”函数)这些不同的API调用在程序中的何处使用。这可能会让我有理由返回API设计器,并根据我的使用方式建议对设计进行更改。感谢您的全面回复!我想澄清一下——看看问题中的json响应(在中编辑),您是否建议使用一个部分car对象来存储我调用vehicle_fleet时得到的car对象,然后使用一个单独的完整car对象来存储vehicle_fleet.car.self返回的项目?是的。您可以从部分继承完整的汽车,但关键是您不能在需要完整汽车的地方使用部分汽车。