Home > database >  Remove property name from the response
Remove property name from the response

Time:09-30

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; }
 }  

Depending on the scenario this cars property will have different representation (either MarketingInfo or CarDetails or ServiceInfo, but not both). case 1: MarketingInfo

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

case 2: ServiceInfo and CarDetails

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

This is how I populate my response

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

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

In the above model representation my response is NOT as I want them to be (because it contains marketingInfoDetails word)

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

where I want to be represented without name "marketingInfoDetails"

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

Please share if you think this response for the described scenario can be modeled better.

CodePudding user response:

Your C# model and result JSON are matching. What you're asking for changes from the start of your question to the end of your question. What you appear to want from the C# model and JSON is to remove the object which your desired example includes alongside a carId property that is not present in your C# models.

You need to remove the intermediate CarInfo class and instead have your list of cars be a common interface which is inherited by CarDetails, ServiceDetails, and MarketingInfo, then you will not see the "MarketingInfoDetails" property in your JSON.

If you were to instead add the carId property to CarInfo and again serialize the C# model to JSON, you will see that your current model matches exactly what you first stated you want the JSON to look like.

CodePudding user response:

If you are using Json.net, you could make use of Conditional Serialization functionality using ShouldSerialize.

To conditionally serialize a property, add a method that returns boolean with the same name as the property and then prefix the method name with ShouldSerialize. The result of the method determines whether the property is serialized. If the method returns true then the property will be serialized, if it returns false then the property will be skipped.

You would need to modify your DTOs to include an additional property and method (for each property you want to make conditional) as the following.

[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; }

For each instance of CarDetails, you could now set the SerializeMarketingInfoDetails or SerializeDetails properties to conditional serialize them.

Demo Code

CodePudding user response:

It'a recommended that you use EmiDefaultValue="true" for datamembers. In the case the proprety is null, it won't be shown in the jsonsince its value is null.

  • Related