C# 如何在具有新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;

我已经将JSON反序列化为一个c#对象,但是JSON不完整,因此缺少一些属性。在反序列化对象时,我没有访问完整JSON的权限。我可以通过进行另一个API调用来获得完整的JSON,但如果不需要的话,我不想进行该调用

我希望我的属性获取程序能够工作,以便在属性不为null时返回该属性。如果为null,它应该调用API以获取完整的JSON并更新类中的所有JsonProperties,然后返回我请求的属性

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返回的项目?是的。您可以从部分继承完整的汽车,但关键是您不能在需要完整汽车的地方使用部分汽车。