Search code examples
c#jsonasp.net-core-webapi.net-6.0

How to make it so that the property is ignored if it has a string type?


I have a model:

public class Data
{
    [JsonPropertyName("id")]
    public string OrderId { get; set; }
    public Order Order { get; set; }
}

I want the property 'Order' to be ignored if the response contains that property of type string and not ignore if object. Maybe, JsonIgnoreAtribute with something options

Third-party service send json to my endpoint. First option has view:

{
    "data": {
        "order": "T5TKlQn-SlCJTZJuUvC05g",
        "id": "T5TKlQn-SlCJTZJuUvC05g"
   }
}

Second option has view:

{
    "data": {
        "order": {
            "id": "dhdjd",
            "name": "test"
        },
        "id": "T5TKlQn-SlCJTZJuUvC05g"
    }
}

And I want to ignore the order property if it has string type

This json is parameter to api:

[HttpPost("order")]
public async Task OrderAsync([FromBody] Data viewModel)
{
    // .. code
}

Solution

  • IMHO it is better to use Newtonsoft.Json because code is much more simple and clear. TextJson will need a custom json converter

    var json1=@"{
        ""data"": {
            ""order"": ""T5TKlQn-SlCJTZJuUvC05g"",
            ""id"": ""T5TKlQn-SlCJTZJuUvC05g""
       }
    }";
    
    var json2=@"{
        ""data"": {
            ""order"": {
                ""id"": ""dhdjd"",
                ""name"": ""test""
            },
            ""id"": ""T5TKlQn-SlCJTZJuUvC05g""
        }
    }";
    
    using Newtonsoft.Json;
    
    Data data = JsonConvert.DeserializeObject<Root>(json1).data;
    

    classes

    
    public class Root
    {
        public Data data {get;set;}
    }
    public class Data
    {
        [JsonProperty("id")]
        [JsonPropertyName("id")]
        public string OrderId { get; set; }
    
        public Order Order { get; set; }
        
        public Data(JToken order)
        {
            if(order.Type==JTokenType.Object)
            Order=order.ToObject<Order>();
        }
    
        public Data() {}
    }
    public class Order
    {
        public string Id { get; set; }
        public string Name { get; set; }
    }
    

    or if you still want to use text.json it will be more complicated

    using System.Text.Json;
    
    var jsonObj = System.Text.Json.Nodes.JsonNode.Parse(json1);
    
    if ( jsonObj.AsObject()["data"]["order"].GetType().ToString()
               != "System.Text.Json.Nodes.JsonObject") 
                        jsonObj.AsObject()["data"]["order"]=null;
    
    var options = new JsonSerializerOptions
    {
        PropertyNameCaseInsensitive = true
    };
    
    var data=jsonObj.Deserialize<Root>(options).data;
    

    api

    [HttpPost("order")]
    public async Task OrderAsync([FromBody]JsonNode jsonObj)
    {
        if (jsonObj.AsObject()["data"]["order"].GetType().ToString()
               != "System.Text.Json.Nodes.JsonObject")
                    jsonObj.AsObject()["data"]["order"] = null;
    
                var options = new JsonSerializerOptions
                {
                    PropertyNameCaseInsensitive = true
                };
    
                 Data data = jsonObj.Deserialize<Root>(options).data;
    
        // .. code
    }