如何使用C#将分层键值对从字符串转换为json?

Al Polden

我有以下http post正文通过chargify的Web钩子发送到asp.net Web api。

id=38347752&event=customer_update&payload[customer][address]=qreweqwrerwq&payload[customer][address_2]=qwerewrqew&payload[customer][city]=ererwqqerw&payload[customer][country]=GB&payload[customer][created_at]=2015-05-14%2004%3A46%3A48%20-0400&payload[customer][email]=a%40test.com&payload[customer][first_name]=Al&payload[customer][id]=8619620&payload[customer][last_name]=Test&payload[customer][organization]=&payload[customer][phone]=01&payload[customer][portal_customer_created_at]=2015-05-14%2004%3A46%3A49%20-0400&payload[customer][portal_invite_last_accepted_at]=&payload[customer][portal_invite_last_sent_at]=2015-05-14%2004%3A46%3A49%20-0400&payload[customer][reference]=&payload[customer][state]=&payload[customer][updated_at]=2015-05-14%2011%3A25%3A19%20-0400&payload[customer][verified]=false&payload[customer][zip]=&payload[site][id]=26911&payload[site][subdomain]=testsubdomain

如何使用C#将此有效负载[客户] [地址] =值等转换为json字符串?

马库斯·萨法尔(Markus Safar)

你当前的问题

如何使用C#将Chargify Webhooks转换为JSON?

可以概括为

如何从字符串中提取键值对,将其转换为相应的层次结构并以JSON返回?

要回答您的问题:

string rawData = "id=38347752&event=customer_update&payload[customer][address]=qreweqwrerwq&payload[customer][address_2]=qwerewrqew&payload[customer][city]=ererwqqerw&payload[customer][country]=GB&payload[customer][created_at]=2015-05-14%2004%3A46%3A48%20-0400&payload[customer][email]=a%40test.com&payload[customer][first_name]=Al&payload[customer][id]=8619620&payload[customer][last_name]=Test&payload[customer][organization]=&payload[customer][phone]=01&payload[customer][portal_customer_created_at]=2015-05-14%2004%3A46%3A49%20-0400&payload[customer][portal_invite_last_accepted_at]=&payload[customer][portal_invite_last_sent_at]=2015-05-14%2004%3A46%3A49%20-0400&payload[customer][reference]=&payload[customer][state]=&payload[customer][updated_at]=2015-05-14%2011%3A25%3A19%20-0400&payload[customer][verified]=false&payload[customer][zip]=&payload[site][id]=26911&payload[site][subdomain]=testsubdomain";
ChargifyWebHook webHook = new ChargifyWebHook(rawData);
JSONNode node = new JSONNode("RootOrWhatEver");

foreach (KeyValuePair<string, string> keyValuePair in webHook.KeyValuePairs)
{
    node.InsertInHierarchy(ChargifyWebHook.ExtractHierarchyFromKey(keyValuePair.Key), keyValuePair.Value);
}

string result = node.ToJSONObject();

使用您指定的输入,结果如下所示(不包含换行符):

{
    "id": "38347752",
    "event": "customer_update",
    "payload": {
                   "customer": {
                                   "address": "qreweqwrerwq",
                                   "address_2": "qwerewrqew",
                                   "city": "ererwqqerw",
                                   "country": "GB",
                                   "created_at": "2015-05-14 04:46:48 -0400",
                                   "email": "[email protected]",
                                   "first_name": "Al",
                                   "id": "8619620",
                                   "last_name": "Test",
                                   "organization": "",
                                   "phone": "01",
                                   "portal_customer_created_at": "2015-05-14 04:46:49 -0400",
                                   "portal_invite_last_accepted_at": "",
                                   "portal_invite_last_sent_at": "2015-05-14 04:46:49 -0400",
                                   "reference": "",
                                   "state": "",
                                   "updated_at": "2015-05-14 11:25:19 -0400",
                                   "verified": "false",
                                   "zip": ""
                               },
                       "site": {
                                   "id": "26911",
                                   "subdomain": "testsubdomain"
                               }
               }
}

由于您的问题不限于1、2或3个级别,因此您显然需要递归解决方案。因此,我创建了一个JSONNode类,该类可以通过将层次结构指定为来插入子级List<string>

如果你把A.B.C作为一个例子,一开始的方法InsertIntoHierarchy是否需要更多层次的检查或不(根据指定的条目的长度,在我们的例子中,我们将得到一个包含列表ABC),如果是的话它插入一个孩子(用作具有指定name级别的容器),并将问题传递给此子级。当然,在该步骤中将删除当前递归级别的名称,因此根据我们的示例,name A将添加具有的容器,并将包含BC将要传递到该容器的列表。如果达到了最后一级的递归,将插入一个包含name和的节点value

要使解决方案正常工作,您将需要以下两个类:

ChargifyWebHook

/// <summary>
/// Represents the chargify web hook class.
/// </summary>
public class ChargifyWebHook
{
    /// <summary>
    /// Indicates whether the raw data has already been parsed or not.
    /// </summary>
    private bool initialized;

    /// <summary>
    /// Contains the key value pairs extracted from the raw data.
    /// </summary>
    private Dictionary<string, string> keyValuePairs;

    /// <summary>
    /// Initializes a new instance of the <see cref="ChargifyWebHook"/> class.
    /// </summary>
    /// <param name="data">The raw data of the web hook.</param>
    /// <exception cref="System.ArgumentException">Is thrown if the sepcified raw data is null or empty.</exception>
    public ChargifyWebHook(string data)
    {
        if (String.IsNullOrEmpty(data))
        {
            throw new ArgumentException("The specified value must neither be null nor empty", data);
        }

        this.initialized = false;
        this.keyValuePairs = new Dictionary<string, string>();
        this.RawData = data;
    }

    /// <summary>
    /// Gets the raw data of the web hook.
    /// </summary>
    public string RawData
    {
        get;
        private set;
    }

    /// <summary>
    /// Gets the key value pairs contained in the raw data.
    /// </summary>
    public Dictionary<string, string> KeyValuePairs
    {
        get
        {
            if (!initialized)
            {
                this.keyValuePairs = ExtractKeyValuesFromRawData(this.RawData);
                initialized = true;
            }

            return this.keyValuePairs;
        }
    }

    /// <summary>
    /// Extracts the key value pairs from the specified raw data.
    /// </summary>
    /// <param name="rawData">The data which contains the key value pairs.</param>
    /// <param name="keyValuePairSeperator">The pair seperator, default is '&'.</param>
    /// <param name="keyValueSeperator">The key value seperator, default is '='.</param>
    /// <returns>The extracted key value pairs.</returns>
    /// <exception cref="System.FormatException">Is thrown if an key value seperator is missing.</exception>
    public static Dictionary<string, string> ExtractKeyValuesFromRawData(string rawData, char keyValuePairSeperator = '&', char keyValueSeperator = '=')
    {
        Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();

        string[] rawDataParts = rawData.Split(new char[] { keyValuePairSeperator });

        foreach (string rawDataPart in rawDataParts)
        {
            string[] keyAndValue = rawDataPart.Split(new char[] { keyValueSeperator });

            if (keyAndValue.Length != 2)
            {
                throw new FormatException("The format of the specified raw data is incorrect. Key value pairs in the following format expected: key=value or key1=value1&key2=value2...");
            }

            keyValuePairs.Add(Uri.UnescapeDataString(keyAndValue[0]), Uri.UnescapeDataString(keyAndValue[1]));
        }

        return keyValuePairs;
    }

    /// <summary>
    /// Extracts the hierarchy from the key, e.g. A[B][C] will result in A, B and C.
    /// </summary>
    /// <param name="key">The key who's hierarchy shall be extracted.</param>
    /// <param name="hierarchyOpenSequence">Specifies the open sequence for the hierarchy speration.</param>
    /// <param name="hierarchyCloseSequence">Specifies the close sequence for the hierarchy speration.</param>
    /// <returns>A list of entries for the hierarchy names.</returns>
    public static List<string> ExtractHierarchyFromKey(string key, string hierarchyOpenSequence = "[", string hierarchyCloseSequence = "]")
    {
        if (key.Contains(hierarchyOpenSequence) && key.Contains(hierarchyCloseSequence))
        {
            return key.Replace(hierarchyCloseSequence, string.Empty).Split(new string[] { hierarchyOpenSequence }, StringSplitOptions.None).ToList();
        }

        if (key.Contains(hierarchyOpenSequence) && !key.Contains(hierarchyCloseSequence))
        {
            return key.Split(new string[] { hierarchyOpenSequence }, StringSplitOptions.None).ToList();
        }

        if (!key.Contains(hierarchyOpenSequence) && key.Contains(hierarchyCloseSequence))
        {
            return key.Split(new string[] { hierarchyCloseSequence }, StringSplitOptions.None).ToList();
        }

        return new List<string>() { key };
    }
}

JSONNode

/// <summary>
/// Represents the JSONNode class.
/// </summary>
public class JSONNode
{
    /// <summary>
    /// Initializes a new instance of the <see cref="JSONNode"/> class.
    /// </summary>
    /// <param name="name">The name of the node.</param>
    /// <param name="value">The value of the node.</param>
    public JSONNode(string name, string value)
    {
        this.Name = name;
        this.Value = value;
        this.Children = new Dictionary<string, JSONNode>();
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="JSONNode"/> class.
    /// </summary>
    /// <param name="name">The name of the node.</param>
    public JSONNode(string name)
        : this(name, string.Empty)
    {
    }

    /// <summary>
    /// Gets the name of the node.
    /// </summary>
    public string Name
    {
        get;
        private set;
    }

    /// <summary>
    /// Gets the children of the node.
    /// </summary>
    public Dictionary<string, JSONNode> Children
    {
        get;
        private set;
    }

    /// <summary>
    /// Gets the value of the node.
    /// </summary>
    public string Value
    {
        get;
        private set;
    }

    /// <summary>
    /// Inserts a new node in the corresponding hierarchy.
    /// </summary>
    /// <param name="keyHierarchy">A list with entries who specify the hierarchy.</param>
    /// <param name="value">The value of the node.</param>
    /// <exception cref="System.ArgumentNullException">Is thrown if the keyHierarchy is null.</exception>
    /// <exception cref="System.ArgumentException">Is thrown if the keyHierarchy is empty.</exception>
    public void InsertInHierarchy(List<string> keyHierarchy, string value)
    {
        if (keyHierarchy == null)
        {
            throw new ArgumentNullException("keyHierarchy");
        }

        if (keyHierarchy.Count == 0)
        {
            throw new ArgumentException("The specified hierarchy list is empty", "keyHierarchy");
        }

        // If we are not in the correct hierarchy (at the last level), pass the problem
        // to the child.
        if (keyHierarchy.Count > 1)
        {
            // Extract the current hierarchy level as key
            string key = keyHierarchy[0];

            // If the key does not already exists - add it as a child.
            if (!this.Children.ContainsKey(key))
            {
                this.Children.Add(key, new JSONNode(key));
            }

            // Remove the current hierarchy from the list and ...
            keyHierarchy.RemoveAt(0);

            // ... pass it on to the just inserted child.
            this.Children[key].InsertInHierarchy(keyHierarchy, value);
            return;
        }

        // If we are on the last level, just insert the node with it's value.
        this.Children.Add(keyHierarchy[0], new JSONNode(keyHierarchy[0], value));
    }

    /// <summary>
    /// Gets the textual representation of this node as JSON entry.
    /// </summary>
    /// <returns>A textual representaiton of this node as JSON entry.</returns>
    public string ToJSONEntry()
    {
        // If there is no child, return the name and the value in JSON format.
        if (this.Children.Count == 0)
        {
            return string.Format("\"{0}\":\"{1}\"", this.Name, this.Value);
        }

        // Otherwise there are childs so return all of them formatted as object.
        StringBuilder builder = new StringBuilder();
        builder.AppendFormat("\"{0}\":", this.Name);
        builder.Append(this.ToJSONObject());

        return builder.ToString();
    }

    /// <summary>
    /// Gets the textual representation of this node as JSON object.
    /// </summary>
    /// <returns>A textual representaiton of this node as JSON object.</returns>
    public string ToJSONObject()
    {
        StringBuilder builder = new StringBuilder();

        builder.Append("{");

        foreach (JSONNode value in this.Children.Values)
        {
            builder.Append(value.ToJSONEntry());
            builder.Append(",");
        }

        builder.Remove(builder.Length - 1, 1);
        builder.Append("}");

        return builder.ToString();
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何使用 C# 将字符串转换为 json?

来自分类Dev

将c#字符串[]转换为json

来自分类Dev

将JSON字符串转换为C#字典

来自分类Dev

将JSON字符串转换为C#字典

来自分类Dev

将字符串转换为JSON对象C#

来自分类Dev

将字符串转换为JSON C#

来自分类Dev

C#将字符串转换为JSON错误

来自分类Dev

c# 将 json 字符串转换为 .csv

来自分类Dev

如何将键值对的字符串转换为数组

来自分类Dev

如何将复杂的字符串转换为键值中带有“”的JSON?

来自分类Dev

如何使用SwiftyJSON将字符串转换为JSON

来自分类Dev

如何使用gson将json转换为字符串

来自分类Dev

如何将Json字符串转换为c#类对象?

来自分类Dev

如何将下面的json字符串转换为C#中的对象列表

来自分类Dev

如何将类似 JSON 的字符串转换为 C# 对象

来自分类Dev

使用 javascript 或 c# 将 JSON 字符串转换为数据数组

来自分类Dev

如何使用C#将逗号分隔的字符串转换为小写

来自分类Dev

如何使用Oracle日期格式将DateTime转换为C#中的字符串

来自分类Dev

如何使用C#将逗号分隔的字符串转换为小写

来自分类Dev

如何使用C#将xml字符串转换为对象

来自分类Dev

如何使用C#将十进制转换为字符串

来自分类Dev

当我们使用winapis将字符串作为参数传递时,如何将c#字符串转换为c ++字符串

来自分类Dev

如何将C#字符串引用转换为Javascript字符串引用

来自分类Dev

使用Roslyn将C#字符串值转换为转义的字符串文字

来自分类Dev

如何在C ++中使用Boost库将类对象转换为json字符串?

来自分类Dev

C#:将字符列表转换为字符串

来自分类Dev

如何将布尔值和数字类型的Json键值转换为字符串类型

来自分类Dev

将键值对的JSON数组转换为Javascript中的JSON字符串数组

来自分类Dev

如何将JSON字符串转换为JSON

Related 相关文章

  1. 1

    如何使用 C# 将字符串转换为 json?

  2. 2

    将c#字符串[]转换为json

  3. 3

    将JSON字符串转换为C#字典

  4. 4

    将JSON字符串转换为C#字典

  5. 5

    将字符串转换为JSON对象C#

  6. 6

    将字符串转换为JSON C#

  7. 7

    C#将字符串转换为JSON错误

  8. 8

    c# 将 json 字符串转换为 .csv

  9. 9

    如何将键值对的字符串转换为数组

  10. 10

    如何将复杂的字符串转换为键值中带有“”的JSON?

  11. 11

    如何使用SwiftyJSON将字符串转换为JSON

  12. 12

    如何使用gson将json转换为字符串

  13. 13

    如何将Json字符串转换为c#类对象?

  14. 14

    如何将下面的json字符串转换为C#中的对象列表

  15. 15

    如何将类似 JSON 的字符串转换为 C# 对象

  16. 16

    使用 javascript 或 c# 将 JSON 字符串转换为数据数组

  17. 17

    如何使用C#将逗号分隔的字符串转换为小写

  18. 18

    如何使用Oracle日期格式将DateTime转换为C#中的字符串

  19. 19

    如何使用C#将逗号分隔的字符串转换为小写

  20. 20

    如何使用C#将xml字符串转换为对象

  21. 21

    如何使用C#将十进制转换为字符串

  22. 22

    当我们使用winapis将字符串作为参数传递时,如何将c#字符串转换为c ++字符串

  23. 23

    如何将C#字符串引用转换为Javascript字符串引用

  24. 24

    使用Roslyn将C#字符串值转换为转义的字符串文字

  25. 25

    如何在C ++中使用Boost库将类对象转换为json字符串?

  26. 26

    C#:将字符列表转换为字符串

  27. 27

    如何将布尔值和数字类型的Json键值转换为字符串类型

  28. 28

    将键值对的JSON数组转换为Javascript中的JSON字符串数组

  29. 29

    如何将JSON字符串转换为JSON

热门标签

归档