-1

I want to make my json deserializer ignore objects with improper values (like string in place of a int) or return null for them and continue to deserialize the rest of a json file.

Here is my json:

{
    "requests":[
        {
            "clientId":"1",
            "requestId":"1",
            "name":"Bułka",
            "quantity":"1",
            "price":"10.00"
        },
        {
            "clientId":"1",
            "requestId":"2.1",
            "name":"Chleb",
            "quantity":"2",
            "price":"15.00"
        },
        {
            "clientId":"1",
            "requestId":"2",
            "name":"Chleb",
            "quantity":"5",
            "price":"15.00"
        },
        {
            "clientId":"2",
            "requestId":"1",
            "name":"Chleb",
            "quantity":"1",
            "price":"10.00"
        }
    ]
}

Here are the classes I'm deserializing to:

class RequestCollection
{
    public List<Request> requests { get; set; }

    public RequestCollection()
    {
        requests = new List<Request>();
    }
}

class Request
{
    public string clientId { get; set; }
    public long requestId { get; set; }
    public string name { get; set; }
    public int quantity { get; set; }
    public double price { get; set; }

    public Request() { }
    public Request(string clientID, long requestID, string name, int quantity, double price)
    {
        this.clientId = clientID;
        this.requestId = requestID;
        this.name = name;
        this.quantity = quantity;
        this.price = price;
    }
}

And here is how I deserialize the file:

requestCollectionLocal = JsonConvert.DeserializeObject<RequestCollection>(json);

As you can see I have improper value of requestId in 2nd object in json file. I want the result of deserialization to be just 3 other objects or all 4 objects with null values instead of improper ones.

Aleks Andreev
  • 7,016
  • 8
  • 29
  • 37
Lordzio
  • 47
  • 5

1 Answers1

0

You can deserialize your json to anonymous type, and then filter result with linq

Define an anonymous type like

var template = new {
  requests = new [] {
    new {
      clientId = "",
      requestId = "",
      name = "",
      quantity = "",
      price = ""
    } 
  }
};

Here you can see that all types are string, so deserialization should work well. Now you should check that it is possible to convert each string to corresponding data type with TryParse. Full code:

var json = "{\r\n    \"requests\":[\r\n        {\r\n            \"clientId\":\"1\",\r\n            \"requestId\":\"1\",\r\n            \"name\":\"Bułka\",\r\n            \"quantity\":\"1\",\r\n            \"price\":\"10.00\"\r\n        },\r\n        {\r\n            \"clientId\":\"1\",\r\n            \"requestId\":\"2.1\",\r\n            \"name\":\"Chleb\",\r\n            \"quantity\":\"2\",\r\n            \"price\":\"15.00\"\r\n        },\r\n        {\r\n            \"clientId\":\"1\",\r\n            \"requestId\":\"2\",\r\n            \"name\":\"Chleb\",\r\n            \"quantity\":\"5\",\r\n            \"price\":\"15.00\"\r\n        },\r\n        {\r\n            \"clientId\":\"2\",\r\n            \"requestId\":\"1\",\r\n            \"name\":\"Chleb\",\r\n            \"quantity\":\"1\",\r\n            \"price\":\"10.00\"\r\n        }\r\n    ]\r\n}";

var template = new { requests = new [] { new {clientId = "", requestId = "", name = "", quantity = "", price = ""} }};
var tempRequestCollection = JsonConvert.DeserializeAnonymousType(json, template);

var result = new RequestCollection
{
    requests = tempRequestCollection.requests
        .Where(r => 
            long.TryParse(r.requestId, out var _)
            && int.TryParse(r.quantity, out var _)
            && double.TryParse(r.price, out var _)
          )
        .Select(r => new Request
        {
            clientId = r.clientId,
            requestId = long.Parse(r.requestId),
            name = r.name,
            quantity = int.Parse(r.quantity),
            price = double.Parse(r.price)
        })
        .ToList()
};
Aleks Andreev
  • 7,016
  • 8
  • 29
  • 37