/// <summary>
/// JObject转换类
/// </summary>
public class ObjectConverter
{
/// <summary>
/// 将JObject转换Key值
/// </summary>
/// <param name="inputObject">输入的JSON对象</param>
/// <param name="propertyPairs">旧key与新key对应关系</param>
/// <param name="bOnlyNecessaryKeys">是否仅保留必要的键值(否则保留全部键值)</param>
/// <param name="bAddSerialNumber">是否添加序列号(仅当value为JArray且序列号键名非空时生效)</param>
/// <param name="sSerialNumberKey">序列号键名</param>
/// <returns>转换后的JObject</returns>
public static JObject Convert(JObject inputObject, Dictionary<string, string> propertyPairs, bool bOnlyNecessaryKeys = true, bool bAddSerialNumber = true, string sSerialNumberKey = "NO")
{
var jObjectResult = new JObject();
try
{
if (null != inputObject && 0 < inputObject.Count && null != propertyPairs && 0 < propertyPairs.Count)
{
var lstKey = propertyPairs.Keys.ToList();
var lstObjectKey = inputObject.Properties().ToList();
for (int i = 0; i < lstObjectKey.Count(); i++)
{
var p = lstObjectKey[i];
var sOldKey = lstKey.FirstOrDefault(k => 0 == string.Compare(p.Name, (k.IndexOf(",") != -1 ? k.Split(',')[0] : k), StringComparison.OrdinalIgnoreCase));
var sTsOldKey = sOldKey;
if (!string.IsNullOrEmpty(sTsOldKey) && sTsOldKey.IndexOf(",") != -1)
{
sOldKey = sTsOldKey.Split(',')[0];
}
var sNewKey = (!string.IsNullOrEmpty(sTsOldKey)) ? propertyPairs[sTsOldKey] : p.Name;
if (bOnlyNecessaryKeys && !propertyPairs.Values.Contains(sNewKey))
{
continue;
}
var jToken = inputObject[p.Name];
if (!string.IsNullOrEmpty(sTsOldKey) && sTsOldKey.IndexOf(",") != -1)
{
jToken = "";
foreach (var sItem in sTsOldKey.Split(','))
{
jToken += inputObject[sItem] + "|";
}
}
if (jToken is JObject)
{
var jObj = (JObject)jToken;
var jObjNew = Convert(jObj, propertyPairs, bOnlyNecessaryKeys, bAddSerialNumber, sSerialNumberKey);
if (null != jObjNew)
{
jObjectResult.Add(sNewKey, bOnlyNecessaryKeys ? KeepNecessaryKeys(jObjNew, propertyPairs.Values.ToList()) : jObjNew);
}
}
else if (jToken is JArray)
{
var jArray = (JArray)jToken;
var jArrayResult = new JArray();
for (int j = 0; j < jArray.Count; j++)
{
var jObject = Convert(jArray[j] as JObject, propertyPairs, bOnlyNecessaryKeys, bAddSerialNumber, sSerialNumberKey);
if (null != jObject)
{
jArrayResult.Add(bOnlyNecessaryKeys ? KeepNecessaryKeys(jObject, propertyPairs.Values.ToList()) : jObject);
}
if (bAddSerialNumber && !string.IsNullOrEmpty(sSerialNumberKey))
{
AddSerialNumber(ref jArrayResult);
}
}
if (jObjectResult.ContainsKey(sNewKey))
{
jObjectResult[sNewKey] = jArrayResult;
}
else
{
jObjectResult.Add(sNewKey, jArrayResult);
}
}
else
{
if (jObjectResult.ContainsKey(sNewKey))
{
jObjectResult[sNewKey] = jToken;
}
else
{
jObjectResult.Add(sNewKey, jToken);
}
}
}
}
}
catch
{
jObjectResult = null;
}
return jObjectResult;
}
/// <summary>
/// 只保留必要的键值
/// </summary>
/// <param name="jObject">要进行处理的对象</param>
/// <param name="lstKey">要保留的键值</param>
/// <returns>处理后的对象</returns>
private static JObject KeepNecessaryKeys(JObject jObject, List<string> lstKey)
{
var jObjectResult = new JObject();
try
{
if (null != jObject && null != lstKey)
{
lstKey.ForEach(p =>
{
if (jObject.ContainsKey(p))
{
jObjectResult.Add(p, jObject[p]);
}
});
}
}
catch
{
jObjectResult = null;
}
return jObjectResult;
}
/// <summary>
/// JArray各对象添加序列号
/// </summary>
/// <param name="jArray">输入的JSON对象</param>
/// <param name="sKey">添加的序列号字段</param>
/// <returns></returns>
public static void AddSerialNumber(ref JArray jArray, string sKey = "NO")
{
try
{
if (null != jArray && 0 < jArray.Count)
{
for (int i = 0; i < jArray.Count; i++)
{
jArray[i][sKey] = i + 1;
}
}
}
catch
{
}
}
/// <summary>
/// 获取JObject的一个值(只处理简单类型,不处理JArray)
/// </summary>
/// <param name="jObject">JSON对象(将尝试转换为JObject)</param>
/// <param name="sKey">键名</param>
/// <param name="bTopLevelOnly">是否只取最高一层级的值(否则将继续取子级)</param>
/// <returns>值</returns>
public static object GetValue(object jObj, string sKey, bool bTopLevelOnly = true)
{
object objResult = null;
if (null == jObj || string.IsNullOrEmpty(sKey))
return objResult;
if (jObj.GetType().Name != "JObject")
return objResult;
var jObject = (JObject)jObj;
if (null == jObject)
{
return objResult;
}
if (jObject.ContainsKey(sKey))
{
var jValue = jObject[sKey];
if (null != jValue && jValue.Type != JTokenType.Array && jValue.Type != JTokenType.Object)
{
objResult = jValue;
}
}
else
{
if (!bTopLevelOnly)
{
var jEnum = jObject.GetEnumerator();
while (jEnum.MoveNext())
{
if (jEnum.Current.Value == null)
continue;
if (jEnum.Current.Value.Type != JTokenType.Object)
continue;
var jSubObject = (JObject)jEnum.Current.Value;
if (null == jSubObject)
continue;
objResult = GetValue(jSubObject, sKey, bTopLevelOnly);
if (null != objResult)
break;
}
}
}
return objResult;
}
}