【问题标题】:Remove property name from the response从响应中删除属性名称
【发布时间】:2021-09-29 22:00:17
【问题描述】:
public class CarsModel
{        
    public int OnStock { get; set; }
    public int Rented { get; set; }
    public List<CarInfo> Cars { get; set; }
}
    
public class CarInfo
{
   [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public CarDetails Details { get; set; }

   [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
   public ServiceInfo ServiceInfo { get; set; }

   [JsonProperty( NullValueHandling = NullValueHandling.Ignore)]
   public MarketingInfo MarketingInfoDetails { get; set; }
 }  

根据场景,此汽车属性将具有不同的表示形式(MarketingInfo 或 CarDetails 或 ServiceInfo,但不能同时具有两者)。 案例 1:MarketingInfo

"onStock": 11,
"rented": 2,
"cars": [{
          "carId": 1,
          "MarketingInfo": {           
            "contactPerson": "John Smith"
          }, ...
        }]
    

案例 2:ServiceInfo 和 CarDetails

"onStock": 11,
"rented": 2,
"cars": [{       
          "ServiceInfo": {           
            "lastService": "2021-01-01"         
          }, 
          "CarDetails": {           
            "carId": 1,
            "lastOwner": "Mister Clark"
          }, ...
        }]

这就是我填写回复的方式

var carsModel = new CarsModel{
    OnStock = 11,
    Rented = 2
};

foreach (var car in cars)
{
    carsModel.Cars.Add(new CarsModel 
    {
        MarketingInfoDetails = new MarketingInfo
        {
            ContactPerson = "John Smith",
            ....
        }
    });
}

在上述模型表示中,我的反应不是我想要的(因为它包含 marketingInfoDetails 字)

Response:
{
  "data" :[{
      "onStock": 11,
      "rented": 2,
          "cars": [
            {
              "marketingInfoDetails": {
                "contactPerson": "John Smith",
                ...
              }
            }]
    }]
}

我想在没有名称“marketingInfoDetails”的情况下被代表

{
    "data" : [{ 
        "onStock" : 11, 
        "rented" : 2, 
        "cars" : [{ "contactPerson" : "John Smith"}] 
    }] 
}

如果您认为对所描述场景的这种响应可以更好地建模,请分享。

【问题讨论】:

    标签: c# json serialization


    【解决方案1】:

    您的 C# 模型和结果 JSON 匹配。您要求从问题开始到问题结束的变化。您似乎希望从 C# 模型和 JSON 中删除所需示例中包含的对象以及 C# 模型中不存在的 carId 属性。

    您需要删除中间的CarInfo 类,而是让您的汽车列表成为由CarDetailsServiceDetailsServiceDetailsMarketingInfo 继承的公共接口,然后您将看不到“MarketingInfoDetails” JSON 中的属性。

    如果您改为将 carId 属性添加到 CarInfo 并再次将 C# 模型序列化为 JSON,您将看到当前模型与您最初声明的 JSON 外观完全匹配。

    【讨论】:

      【解决方案2】:

      如果您使用 Json.net,您可以使用 Conditional Serialization functionality 使用 ShouldSerialize

      要有条件地序列化属性,请添加一个返回与属性同名的布尔值的方法,然后在方法名称前加上 ShouldSerialize。方法的结果决定了属性是否被序列化。如果方法返回true,则该属性将被序列化,如果返回false,则该属性将被跳过。

      您需要修改您的 DTO 以包含一个额外的属性和方法(对于您要设置为条件的每个属性),如下所示。

      [JsonIgnore]
      public bool SerializeDetails{get;set;} = true;
          
      public bool ShouldSerializeDetails() =>SerializeDetails;
      
      [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
      public CarDetails Details { get; set; }
      
      
      [JsonIgnore]
      public bool SerializeMarketingInfoDetails{get;set;} = true;
      public bool ShouldSerializeMarketingInfoDetails() =>SerializeMarketingInfoDetails;
          
      [JsonProperty( NullValueHandling = NullValueHandling.Ignore)]
      public MarketingInfo MarketingInfoDetails { get; set; }
      

      对于 CarDetails 的每个实例,您现在可以设置 SerializeMarketingInfoDetailsSerializeDetails 属性以有条件地序列化它们。

      Demo Code

      【讨论】:

      • 不知道这个。不确定我是否想用额外的属性填充我的 DTO,只是为了在这种特殊情况下控制序列化,尽管链接文档中的示例是有效的
      【解决方案3】:

      建议您对数据成员使用 EmiDefaultValue="true"。 如果proprety为null,则不会在json中显示,因为它的值为null。

      【讨论】:

      • 这不是提问者试图解决的问题
      猜你喜欢
      • 2017-04-24
      • 1970-01-01
      • 2016-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多