简体   繁体   中英

Best way to Deserialize JSON to Dynamic using C#

I'd like to know which is the best way do Deserialize to Dynamic, using NewtonSoft.Json and C#

The code below works, but I didn't like it. I would like to simplify it, using "named properties".

The main purpose is to get the last object named "results". It is an array of objects.

I know I can use a response object, but I need to use a dynamic or generic object.

        var searchprod = wscli.BuscarImagensPorProdutoId(prodSku.ToString());
        dynamic obj = JsonConvert.DeserializeObject<dynamic>(searchprod.Result.ToString());
        dynamic obj1 = obj.results.ToString();
        dynamic obj2 = JsonConvert.DeserializeObject<dynamic>(obj1);
        dynamic results = ((JContainer)obj2).ToList();

        if (results != null)
        {
            foreach (IEnumerable<JToken> item in results)
            {
                var prodId = item.ToList()[0];//id is first position
                var id = ((JProperty)prodId).Value.ToString();

                if (!string.IsNullOrEmpty(id))
                {
                    //Delete image
                    var res = await wscli.ExcluirImagemProduto(id);

                    if (res == null || res is string)
                    {
                        throw new Exception($"Error image {id}. Details: {(res == null ? "null" : res.ToString())}");
                    }

                    if (res.status == null || res.status.ToString() != "OK")
                    {
                        throw new Exception($"Error image {id} and product {prodSku}. Details: {JsonConvert.SerializeObject(res)}");
                    }
                }
            }
        }

Json:

{  
    "count": 5,  
    "next": null,  
    "previous": null,  
    "results": [    
    {      
        "id": 62217,      
        "image": "https://io.com/image1.jpg",      
        "position": 5,      
        "title": null,      
        "video": null,      
        "add_date": "2022-07-06T22:13:14.538307",      
        "change_date": "2022-07-06T22:13:14.538331",      
        "product": 12528,      
        "skus": []    
    },    
    {      
        "id": 62216,      
        "image": "https://io.com/image2.jpg",      
        "position": 4,      
        "title": null,      
        "video": null,      
        "add_date": "2022-07-06T22:13:00.435415",      
        "change_date": "2022-07-06T22:13:00.435436",      
        "product": 12528,      
        "skus": []    
    },    
    {      
        "id": 62215,      
        "image": "https://io.com/image3.jpg",      
        "position": 3,      
        "title": null,      
        "video": null,      
        "add_date": "2022-07-06T22:12:51.071782",      
        "change_date": "2022-07-06T22:12:51.071808",      
        "product": 12528,      
        "skus": []    
    },    
    {      
        "id": 62214,      
        "image": "https://io.com/image4.jpg",      
        "position": 2,      
        "title": null,      
        "video": null,      
        "add_date": "2022-07-06T22:12:35.943846",      
        "change_date": "2022-07-06T22:12:35.943871",      
        "product": 12528,      
        "skus": []    
    },    
    {      
        "id": 62213,      
        "image": "https://io.com/image5.jpg",      
        "position": 1,      
        "title": null,      
        "video": null,      
        "add_date": "2022-07-06T22:12:17.221066",      
        "change_date": "2022-07-06T22:12:17.221089",      
        "product": 12528,      
        "skus": []    
    }]
}

Thanks

It's not super clear what you don't like about what you have, but if you're looking to be able to access things by path / property name, something like this might work out for you. (getting strings into C# annoys me, I popped it to a file)

[TestMethod]
        public void GetNode()
        {
            string jsonString = File.ReadAllText("json1.json");
            Assert.IsNotNull(jsonString);

            JObject jObject = JObject.Parse(jsonString);
            // selects the node with results
            var resultsNode = jObject.SelectToken("$..results");
            foreach (JToken item in resultsNode)
            {
                Console.WriteLine(item["image"]);
            }
                
        }

I think reading this article can be useful. https://inspiration.nlogic.ca/en/a-comparison-of-newtonsoft.json-and-system.text.json

  1. If you have used Newtonsoft.Json features in your existing projects that are missing in System.Text.Json or have heavily decorated your DTO's with several attributes from Newtonsoft.Json, you will probably encounter many obstacles during migration.
  2. If you are starting a new project, I would recommend using System.Text.Json. Microsoft is constantly improving System.Text.Json and there have been significant improvements between .Net Core 3.1 and .Net 5.0 and Microsoft has already started planning for .Net 6.0.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM