我有以下http帖子正文通过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#将此有效负载[customer] [address] = value等转换为json字符串?
答案 0 :(得分:0)
你当前的问题
如何使用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": "a@test.com",
"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
检查是否需要更多级别(取决于指定条目的长度,在我们的例子中,我们将得到一个包含A
,B
和C
的列表,如果是这样,它会插入一个具有指定name
级别的子项(用作容器)并将问题传递给此儿童。当然,在该步骤中删除了当前递归级别的名称,因此根据我们的示例,将添加包含name
A
的容器,并且列表包含B
和{{1会被传递给这个容器。如果达到最后一级递归,将插入包含C
和name
的节点。
要使解决方案正常运行,您需要以下两个类:
<强> ChargifyWebHook 强>
value
<强> JSONNode 强>
/// <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 };
}
}