简体   繁体   中英

Unable to map JSON response to a predefined class in C# / dynamic property name

I have a class which basically contains a property like this:

public class Msg
{
    [JsonProperty(PropertyName = "XD1703301059485299")]
    public Shipping shipping { get; set; }
}

the problem is in this part:

 [JsonProperty(PropertyName = "XD1703301059485299")]

And the dynamic property name that I get from server...

This property name can be any name that server returns. In this particular case it's able to map the JSON to my class since the property names are same... But when server returns something like this:

XS12394124912841

The object is the null....

How can I resolve property name to be dynamic ? Can someone help me out?

PS This is the JSON response itself:

{"status":1,"msg":{"dynamic_name":{"order_sn":"12312313123123123","order_status":"0","shipping_info":[{"shipping_name":"","shipping_no":"","shipping_img":"","shipping_code":"","shipping_time":"","track_goods":""}]}},"errcode":0}

You can implement something like this with the help of System.Web.Helpers

using (StreamReader r = new StreamReader("sample.json"))
{
    string json = r.ReadToEnd();
    dynamic data = Json.Decode(json); 
    Console.WriteLine(data["your_property"]);
}

Here sample.json contains your sample JSON response.

So I don't think this problem is as dynamic as it sounds. You can probably just convert to a dyanmic object and explicitly handle conversions.

Sample solution below. I inserted a few values to show conversion works as expected.

Add nuget package Newtonsoft.Json

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;

namespace Serialize
{
    public class Shipping
    {
        [JsonProperty(PropertyName = "shipping_name")]
        public String Name { get; set; }

        [JsonProperty(PropertyName = "shipping_img")]
        public String Img { get; set; }

        [JsonProperty(PropertyName = "shipping_code")]
        public String Code { get; set; }
    }

    public class Order
    {
        public Shipping shipping { get; set; }

        [JsonProperty(PropertyName = "order_sn")]
        public string SerialNumber { get; set; }

        [JsonProperty(PropertyName = "order_status")]
        public string Status { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            /*
             {
             "status":1,
             "msg": {
                 "dynamic_name": {
                     "order_sn": "12312313123123123",
                     "order_status":"0",
                     "shipping_info": [{
                         "shipping_name":"name",
                         "shipping_no":"",
                         "shipping_img":"img",
                         "shipping_code":"code",
                         "shipping_time":"",
                         "track_goods":""
                     }]
                 }
             },
             "errcode":0
             }
             * */
            var raw = "{ \"status\":1, \"msg\":{\"dynamic_name\":{\"order_sn\":\"12312313123123123\",\"order_status\":\"0\",\"shipping_info\":[{\"shipping_name\":\"name\",\"shipping_no\":\"\",\"shipping_img\":\"img\",\"shipping_code\":\"code\",\"shipping_time\":\"\",\"track_goods\":\"\"}]}},\"errcode\":0}";

            var incomingOrder = new Order();

            // properties on dynamic objects are evaluated at runtime
            dynamic msgJson = JObject.Parse(raw);

            // you'll want exception handling around all of this
            var order = msgJson.msg.dynamic_name;

            // accessing properties is easy (if they exist, as these do)
            incomingOrder.SerialNumber = order.order_sn;
            incomingOrder.Status = order.order_status;

            // JObject cast might not be necessary. need to check for array elements, etc.
            // but it's simple to serialize into a known type
            incomingOrder.shipping = ((JObject)(order.shipping_info[0])).ToObject<Shipping>();

        }
    }
}

Alternatively, if the property name is given at runtime, you can dereference properties with the indexer getter

        dynamic msgJson = JObject.Parse(raw);

        JObject order = msgJson.msg["XS12394124912841"];

        incomingOrder.SerialNumber = order["order_sn"].ToObject<string>();
        incomingOrder.Status = order["order_status"].ToObject<string>();
        incomingOrder.shipping = order["shipping_info"][0].ToObject<Shipping>();

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