using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using CYQ.Data.Table;
using System.Data;
using System.Text.RegularExpressions;
using CYQ.Data.SQL;
using System.IO;
using System.Reflection;
using CYQ.Data.Xml;
using System.ComponentModel;
using CYQ.Data.Tool;
namespace CYQ.Data.Json
{
///
/// Json class for you easy to operate json
/// 功能全面的json帮助类
///
public partial class JsonHelper
{
internal static EscapeOp DefaultEscape
{
get
{
return (EscapeOp)Enum.Parse(typeof(EscapeOp), AppConfig.Json.Escape);
}
}
#region 实例属性
public JsonHelper()
{
}
/// with easyui header ?是否带输出头
public JsonHelper(bool addHead)
{
_AddHead = addHead;
}
/// first row with table schema ?
/// 是否首行带表结构[MDataTable.LoadFromJson可以还原表的数据类型]
public JsonHelper(bool addHead, bool addSchema)
{
_AddHead = addHead;
_AddSchema = addSchema;
}
#region 属性
///
/// Escape options
/// 转义符号
///
public EscapeOp Escape = JsonHelper.DefaultEscape;
///
/// convert filed to lower
/// 是否将名称转为小写
///
public bool IsConvertNameToLower = false;
///
/// convert enum to string
/// 是否将枚举转字符串
///
public bool IsConvertEnumToString = false;
///
/// convert enum to DescriptionAttribute
/// 是否将枚举转属性描述
///
public bool IsConvertEnumToDescription = false;
///
/// formate datetime
/// 日期的格式化(默认:yyyy-MM-dd HH:mm:ss)
///
public string DateTimeFormatter = "yyyy-MM-dd HH:mm:ss";
private const string brFlag = "[#
]";
RowOp _RowOp = RowOp.IgnoreNull;
///
/// filter json data
/// Json输出行数据的过滤选项
///
public RowOp RowOp
{
get
{
return _RowOp;
}
set
{
_RowOp = value;
}
}
//internal BreakOp BreakOp
//{
// get
// {
// switch (_RowOp)
// {
// case Table.RowOp.IgnoreNull:
// return Table.BreakOp.Null;
// default:
// return Table.BreakOp.None;
// }
// }
//}
private bool _AddHead = false;
private bool _AddSchema = false;
///
/// is success
/// 是否成功
///
public bool Success
{
get
{
return rowCount > 0;
}
}
private string errorMsg = "";
///
/// Error message
/// 错误提示信息
///
public string ErrorMsg
{
get
{
return errorMsg;
}
set
{
errorMsg = value;
}
}
private int rowCount = 0;
///
/// data rows count
/// 当前返回的行数
///
public int RowCount
{
get
{
return rowCount;
}
set
{
rowCount = value;
}
}
private int total;
///
/// totla count
/// 所有记录的总数(多数用于分页的记录总数)。
///
public int Total
{
get
{
if (total == 0)
{
return rowCount;
}
return total;
}
set
{
total = value;
}
}
#endregion
private List bodyItems = new List(128);
private StringBuilder headText = new StringBuilder();
private StringBuilder footText = new StringBuilder();
///
/// flag a json is end and start a new json
/// 添加完一个Json数据后调用此方法换行
///
public void AddBr()
{
bodyItems.Add(brFlag);
rowCount++;
}
/////
///// 调用后将替换默认的Head (AddHead must be true)
///// 添加底部数据(只有AddHead为true情况才能添加数据)
/////
//public void AddHead(string name, string value)
//{
// AddHead(name, value, false);
//}
//public void AddHead(string name, string value, bool noQuotes)
//{
// if (_AddHead)
// {
// headText.Append(",");
// headText.Append(Format(name, value, noQuotes));
// }
//}
///
/// attach json data (AddHead must be true)
/// 添加底部数据(只有AddHead为true情况才能添加数据)
///
public void AddFoot(string name, string value)
{
AddFoot(name, value, false);
}
public void AddFoot(string name, string value, bool noQuotes)
{
if (_AddHead)
{
footText.Append(",");
footText.Append(Format(name, value, noQuotes));
}
}
///
/// add json key value
/// 添加一个字段的值
///
public void Add(string name, string value)
{
bodyItems.Add(Format(name, value, false));
}
/// value is no quotes
/// 值不带引号
public void Add(string name, string value, bool noQuotes)
{
bodyItems.Add(Format(name, value, noQuotes));
}
public void Add(string name, object value)
{
if (value != null)
{
string v = null;
Type t = value.GetType();
if (t.IsEnum)
{
bool descriptionNoValue = true;
if (IsConvertEnumToDescription)
{
FieldInfo field = t.GetField(value.ToString());
if (field != null)
{
DescriptionAttribute da = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
if (da != null)
{
Add(name, da.Description, false);
descriptionNoValue = false;
}
}
}
if (descriptionNoValue)
{
if (IsConvertEnumToString)
{
Add(name, value.ToString(), false);
}
else
{
Add(name, ((int)value).ToString(), true);
}
}
}
else
{
DataGroupType group = DataType.GetGroup(DataType.GetSqlType(t));
bool noQuotes = group == DataGroupType.Number || group == DataGroupType.Bool;
if (group == DataGroupType.Object)
{
v = ToJson(value);
}
else
{
v = Convert.ToString(value);
if (group == DataGroupType.Bool)
{
v = v.ToLower();
}
}
Add(name, v, noQuotes);
}
}
else
{
Add(name, "null", true);
}
}
private string Format(string name, string value, bool children)
{
value = value ?? "";
children = children && !string.IsNullOrEmpty(value);
if (!children && value.Length > 1 &&
((value[0] == '{' && value[value.Length - 1] == '}') || (value[0] == '[' && value[value.Length - 1] == ']')))
{
children = IsJson(value);
}
if (!children)
{
SetEscape(ref value);
}
StringBuilder sb = new StringBuilder();
sb.Append("\"");
sb.Append(name);
sb.Append("\":");
sb.Append(!children ? "\"" : "");
sb.Append(value);
sb.Append(!children ? "\"" : "");
return sb.ToString();
//return "\"" + name + "\":" + (!children ? "\"" : "") + value + (!children ? "\"" : "");//;//.Replace("\",\"", "\" , \"").Replace("}{", "} {").Replace("},{", "}, {")
}
///
/// out json result
/// 输出Json字符串
///
public override string ToString()
{
int capacity = 100;
if (bodyItems.Count > 0)
{
capacity = bodyItems.Count * bodyItems[0].Length;
}
StringBuilder sb = new StringBuilder(capacity);//
if (_AddHead)
{
if (headText.Length == 0)
{
sb.Append("{");
sb.Append("\"rowcount\":");
sb.Append(rowCount);
sb.Append(",");
sb.Append("\"total\":");
sb.Append(Total);
sb.Append(",");
sb.Append("\"errormsg\":\"");
sb.Append(errorMsg);
sb.Append("\",");
sb.Append("\"success\":");
sb.Append(Success.ToString().ToLower());
sb.Append(",");
sb.Append("\"rows\":");
}
else
{
sb.Append(headText.ToString());
}
}
if (bodyItems.Count == 0)
{
if (_AddHead)
{
sb.Append("[]");
}
}
else
{
if (bodyItems[bodyItems.Count - 1] != brFlag)
{
AddBr();
}
if (_AddHead || rowCount > 1)
{
sb.Append("[");
}
char left = '{', right = '}';
string[] items = bodyItems[0].Split(':');
if (bodyItems[0] != brFlag && (items.Length == 1 || !bodyItems[0].Trim('"').Contains("\"")))
{
//说明为数组
left = '[';
right = ']';
}
sb.Append(left);
int index = 0;
foreach (string val in bodyItems)
{
index++;
if (val != brFlag)
{
sb.Append(val);
sb.Append(",");
}
else
{
if (sb[sb.Length - 1] == ',')
{
sb.Remove(sb.Length - 1, 1);//性能优化(内部时,必须多了一个“,”号)。
// sb = sb.Replace(",", "", sb.Length - 1, 1);
}
sb.Append(right);
sb.Append(",");
if (index < bodyItems.Count)
{
sb.Append(left);
}
}
}
if (sb[sb.Length - 1] == ',')
{
sb.Remove(sb.Length - 1, 1);
}
//sb = sb.Replace(",", "", sb.Length - 1, 1);//去除最后一个,号。
//sb.Append("}");
if (_AddHead || rowCount > 1)
{
sb.Append("]");
}
}
if (_AddHead)
{
sb.Append(footText.ToString());
sb.Append("}");
}
return sb.ToString();
//string json = sb.ToString();
//if (AppConfig.IsWeb && Escape == EscapeOp.Yes)
//{
// json = json.Replace("\n", "
");
//}
//if (Escape != EscapeOp.No) // Web应用
//{
// json = json.Replace("\t", " ").Replace("\r", " ");
//}
//return json;
}
/// end with [] ?
///
public string ToString(bool arrayEnd)
{
string result = ToString();
if (arrayEnd && !result.StartsWith("["))
{
result = '[' + result + ']';
}
return result;
}
#endregion
///
/// check string is json
/// 检测是否Json格式的字符串
///
public static bool IsJson(string json)
{
return JsonSplit.IsJson(json, true);
}
/// the index of the error char
/// 错误的字符索引
public static bool IsJson(string json, out int errIndex)
{
return JsonSplit.IsJson(json, true, out errIndex);
}
public static T GetValue(string json, string key)
{
string v = GetValue(json, key);
return ConvertTool.ChangeType(v);
}
public static T GetValue(string json, string key, EscapeOp op)
{
string v = GetValue(json, key, op);
return ConvertTool.ChangeType(v);
}
public static string GetValue(string json, string key)
{
return GetValue(json, key, DefaultEscape);
}
///
/// Get json value
/// 获取Json字符串的值
///
/// the name or key of json
/// 键值(有层级时用:XXX.YYY.ZZZ)
///
public static string GetValue(string json, string key, EscapeOp op)
{
string value = GetSourceValue(json, key);
return UnEscape(value, op);
}
///
/// Json 返回值是否为true(包含"success":true)
///
///
///
public static bool IsSuccess(string json)
{
return GetValue(json, "success");
}
private static string GetSourceValue(string json, string key)
{
string result = string.Empty;
if (!string.IsNullOrEmpty(json))
{
Dictionary jsonDic = Split(json);//先取top1
if (jsonDic != null && jsonDic.Count > 0 && jsonDic.ContainsKey(key))
{
return jsonDic[key];
}
string[] items = key.Split('.');
string fKey = items[0];
int i = -1;
int fi = key.IndexOf('.');
if (int.TryParse(fKey, out i))//数字
{
List> jsonList = JsonSplit.Split(json, i + 1);
if (i < jsonList.Count)
{
Dictionary numJson = jsonList[i];
if (items.Length == 1)
{
result = ToJson(numJson);
}
else if (items.Length == 2) // 0.xxx
{
string sKey = items[1];
if (numJson.ContainsKey(sKey))
{
result = numJson[sKey];
}
}
else
{
return GetSourceValue(ToJson(numJson), key.Substring(fi + 1));
}
}
}
else // 非数字
{
if (jsonDic != null && jsonDic.Count > 0)
{
if (items.Length == 1)
{
if (jsonDic.ContainsKey(fKey))
{
result = jsonDic[fKey];
}
}
else if (jsonDic.ContainsKey(fKey)) // 取子集
{
return GetSourceValue(jsonDic[fKey], key.Substring(fi + 1));
}
}
}
}
return result;
}
///
/// a easy method for you to return a json
/// 返回Json格式的结果信息
///
public static string OutResult(bool result, string msg)
{
return OutResult(result, msg, false);
}
/// no ""
public static string OutResult(bool result, string msg, bool noQuates)
{
JsonHelper js = new JsonHelper(false, false);
js.Add("success", result.ToString().ToLower(), true);
js.Add("msg", msg, noQuates);
return js.ToString();
}
public static string OutResult(bool result, object msgObj)
{
return OutResult(result, msgObj, null, null);
}
public static string OutResult(bool result, object msgObj, string name, object value, params object[] nameValues)
{
//JsonHelper js = new JsonHelper(false, false);
//js.Add("success", result.ToString().ToLower(), true);
//if (msgObj is string)
//{
// js.Add("msg", Convert.ToString(msgObj));
//}
//else
//{
// js.Add("msg", ToJson(msgObj), true);
//}
int num = name == null ? 2 : 4;
object[] nvs = new object[nameValues.Length + num];
nvs[0] = "msg";
nvs[1] = msgObj;
if (num == 4)
{
nvs[2] = name;
nvs[3] = value;
}
if (nameValues.Length > 0)
{
nameValues.CopyTo(nvs, num);
}
return OutResult("success", result, nvs);
}
public static string OutResult(string name, object value, params object[] nameValues)
{
JsonHelper js = new JsonHelper();
js.Add(name, value);
for (int i = 0; i < nameValues.Length; i++) // 1
{
if (i % 2 == 0)
{
string k = Convert.ToString(nameValues[i]);
i++;
object v = i == nameValues.Length ? null : nameValues[i];
js.Add(k, v);
}
}
return js.ToString();
}
///
/// split json to dicationary
/// 将Json分隔成键值对。
///
public static Dictionary Split(string json)
{
if (!string.IsNullOrEmpty(json))
{
json = json.Trim();
if (json[0] != '{' && json[0] != '[')
{
json = ToJson(json);
}
List> result = JsonSplit.Split(json, 1);
if (result != null && result.Count > 0)
{
return result[0];
}
}
return new Dictionary(StringComparer.OrdinalIgnoreCase);
}
//public static List> SplitArray(string jsonArray)
//{
// return SplitArray(jsonArray, DefaultEscape);
//}
///
/// split json to dicationary array
/// 将Json 数组分隔成多个键值对。
///
public static List> SplitArray(string jsonArray)
{
if (string.IsNullOrEmpty(jsonArray))
{
return null;
}
jsonArray = jsonArray.Trim();
return JsonSplit.Split(jsonArray);
}
private void SetEscape(ref string value)
{
if (Escape == EscapeOp.No) { return; }
bool isInsert = false;
int len = value.Length;
StringBuilder sb = new StringBuilder(len + 10);
for (int i = 0; i < len; i++)
{
char c = value[i];
if (Escape == EscapeOp.Encode)
{
if (c < 32 || c == '"' || c == '\\')
{
sb.AppendFormat("@#{0}#@", (int)c);
isInsert = true;
}
else { sb.Append(c); }
continue;
}
if (c < 32)
{
#region 十六进制符号处理
switch (c)
{
case '\n':
sb.Append("\\n");//直接替换追加。
break;
case '\t':
if (Escape == EscapeOp.Yes)
{
sb.Append("\\t");//直接替换追加
}
break;
case '\r':
if (Escape == EscapeOp.Yes)
{
sb.Append("\\r");//直接替换追加
}
break;
default:
break;
}
#endregion
// '\n'=10 '\r'=13 '\t'=9 都会被过滤。
isInsert = true;
continue;
}
#region 双引号和转义符号处理
switch (c)
{
case '"':
isInsert = true;
sb.Append("\\");
//if (i == 0 || value[i - 1] != '\\')//这个是强制转,不然整体格式有问题。
//{
// isInsert = true;
// sb.Append("\\");
//}
break;
case '\\':
//if (i < len - 1)
//{
// switch (value[i + 1])
// {
// // case '"':
// case 'n':
// case 'r'://r和t要转义,不过出事。
// case 't':
// isInsert = true;
// sb.Append("\\");
// break;
// default:
// //isOK = true;
// break;
// }
//}
bool isOK = Escape == EscapeOp.Yes;// || (i != 0 && i == len - 1 && value[i - 1] != '\\');// 如果是以\结尾,(非\\结尾时, 这部分是强制转,不会然影响整体格式)
if (!isOK && Escape == EscapeOp.Default && len > 1 && i < len - 1)//中间
{
switch (value[i + 1])
{
// case '"':
case 'n':
//case 'r'://r和t要转义,不过出事。
//case 't':
break;
default:
isOK = true;
break;
}
}
if (isOK)
{
isInsert = true;
sb.Append("\\");
}
break;
}
#endregion
sb.Append(c);
}
if (isInsert)
{
value = null;
value = sb.ToString();
}
else { sb = null; }
}
///
/// 解码替换数据转义符
///
public static string UnEscape(string result, EscapeOp op)
{
if (op == EscapeOp.No) { return result; }
if (op == EscapeOp.Encode)
{
if (result.IndexOf("@#") > -1 && result.IndexOf("#@") > -1) // 先解系统编码
{
MatchCollection matchs = Regex.Matches(result, @"@#(\d{1,2})#@", RegexOptions.Compiled);
if (matchs != null && matchs.Count > 0)
{
List keys = new List(matchs.Count);
foreach (Match match in matchs)
{
if (match.Groups.Count > 1)
{
int code = int.Parse(match.Groups[1].Value);
string charText = ((char)code).ToString();
result = result.Replace(match.Groups[0].Value, charText);
}
}
}
}
return result;
}
if (result.IndexOf("\\") > -1)
{
bool has = result.IndexOf("\\\\") > -1;
if (has)
{
result = result.Replace("\\\\", "#=#");
}
if (op == EscapeOp.Yes)
{
result = result.Replace("\\t", "\t").Replace("\\r", "\r");
}
result = result.Replace("\\\"", "\"").Replace("\\n", "\n");//.Replace("\\\\","\\");
if (has)
{
result = result.Replace("#=#", "\\");
}
}
return result;
}
}
// 扩展交互部分
public partial class JsonHelper
{
///
/// 用于控制自循环的层级判断。
///
internal int Level = 1;
///
/// 用于自循环检测列表。
///
internal MDictionary LoopCheckList = new MDictionary();
///
/// Fill obj and get json from ToString() method
/// 从数据表中取数据填充,最终可输出json字符串
///
public void Fill(MDataTable table)
{
if (table == null)
{
ErrorMsg = "MDataTable object is null";
return;
}
if (_AddSchema)
{
Fill(table.Columns, false);
}
//RowCount = table.Rows.Count;
Total = table.RecordsAffected;
if (table.Rows.Count > 0)
{
for (int i = 0; i < table.Rows.Count; i++)
{
Fill(table.Rows[i]);
}
}
}
///
/// Fill obj and get json from ToString() method
/// 从数据行中取数据填充,最终可输出json字符串
///
public void Fill(MDataRow row)
{
if (row == null)
{
ErrorMsg = "MDataRow object is null";
return;
}
for (int i = 0; i < row.Count; i++)
{
MDataCell cell = row[i];
if (cell.IsJsonIgnore)
{
continue;
}
if (_RowOp == RowOp.None || (!cell.IsNull && (cell.Struct.IsPrimaryKey || cell.State >= (int)_RowOp)))
{
#region MyRegion
string name = row[i].ColumnName;
if (IsConvertNameToLower)
{
name = name.ToLower();
}
string value = cell.ToString();
DataGroupType group = DataType.GetGroup(cell.Struct.SqlType);
bool noQuot = group == DataGroupType.Number || group == DataGroupType.Bool;
if (cell.IsNull)
{
value = "null";
noQuot = true;
}
else
{
if (group == DataGroupType.Bool || (cell.Struct.MaxSize == 1 && group == DataGroupType.Number)) // oracle 下的number 1会处理成bool类型
{
value = value.ToLower();
}
else if (group == DataGroupType.Date)
{
DateTime dt;
if (DateTime.TryParse(value, out dt))
{
value = dt.ToString(DateTimeFormatter);
}
}
else if (group == DataGroupType.Object)
{
int hash = cell.Value.GetHashCode();
//检测是否循环引用
if (LoopCheckList.ContainsKey(hash))
{
//continue;
int level = LoopCheckList[hash];
if (level < Level)
{
continue;
}
else
{
LoopCheckList[hash] = Level;//更新级别
}
}
else
{
LoopCheckList.Add(hash, Level);
}
Type t = cell.Struct.ValueType;
if (t.FullName == "System.Object")
{
t = cell.Value.GetType();
}
if (t.Name == "Byte[]")
{
value = Convert.ToBase64String(cell.Value as byte[]);
}
else if (t.Name == "String")
{
value = cell.StringValue;
}
else
{
if (cell.Value is IEnumerable)
{
int len = ReflectTool.GetArgumentLength(ref t);
if (len <= 1)//List
{
JsonHelper js = new JsonHelper(false, false);
js.Level = Level + 1;
js.LoopCheckList = LoopCheckList;
js.Escape = Escape;
js._RowOp = _RowOp;
js.DateTimeFormatter = DateTimeFormatter;
js.IsConvertNameToLower = IsConvertNameToLower;
if (cell.Value is MDataRowCollection)
{
MDataTable dtx = (MDataRowCollection)cell.Value;
js.Fill(dtx);
}
else
{
js.Fill(cell.Value);
}
value = js.ToString(true);
noQuot = true;
}
else if (len == 2)//Dictionary
{
MDataRow dicRow = MDataRow.CreateFrom(cell.Value);
dicRow.DynamicData = LoopCheckList;
value = dicRow.ToJson(RowOp, IsConvertNameToLower, Escape);
noQuot = true;
}
}
else
{
if (!t.FullName.StartsWith("System."))//普通对象。
{
MDataRow oRow = new MDataRow(TableSchema.GetColumnByType(t));
oRow.DynamicData = LoopCheckList;
oRow.LoadFrom(cell.Value);
value = oRow.ToJson(RowOp, IsConvertNameToLower, Escape);
noQuot = true;
}
else if (t.FullName == "System.Data.DataTable")
{
MDataTable dt = cell.Value as DataTable;
dt.DynamicData = LoopCheckList;
value = dt.ToJson(false, false, RowOp, IsConvertNameToLower, Escape);
noQuot = true;
}
}
}
}
}
Add(name, value, noQuot);
#endregion
}
}
AddBr();
}
///
/// 从数据结构填充,最终可输出json字符串。
///
/// 数据结构
/// false:输出单行的[列名:数据类型];true:输出多行的完整的数据结构
public void Fill(MDataColumn column, bool isFullSchema)
{
if (column == null)
{
ErrorMsg = "MDataColumn object is null";
return;
}
if (isFullSchema)
{
if (!string.IsNullOrEmpty(column.TableName))
{
_AddHead = true;
headText.Append("{");
headText.Append("\"TableName\":\"" + column.TableName + "\",");
headText.Append("\"Description\":\"" + column.Description + "\",");
headText.Append("\"RelationTables\":\"" + string.Join(",", column.RelationTables.ToArray()) + "\",");
headText.Append("\"Columns\":");
}
foreach (MCellStruct item in column)
{
Add("ColumnName", item.ColumnName);
Add("SqlType", item.ValueType.FullName);
Add("SqlTypeName", item.SqlTypeName);
Add("IsAutoIncrement", item.IsAutoIncrement.ToString().ToLower(), true);
Add("IsCanNull", item.IsCanNull.ToString().ToLower(), true);
Add("MaxSize", item.MaxSize.ToString(), true);
Add("Scale", item.Scale.ToString().ToLower(), true);
Add("IsPrimaryKey", item.IsPrimaryKey.ToString().ToLower(), true);
Add("DefaultValue", Convert.ToString(item.DefaultValue));
Add("Description", item.Description);
//新增属性
Add("TableName", item.TableName);
Add("IsUniqueKey", item.IsUniqueKey.ToString().ToLower(), true);
Add("IsForeignKey", item.IsForeignKey.ToString().ToLower(), true);
Add("FKTableName", item.FKTableName);
AddBr();
}
}
else
{
for (int i = 0; i < column.Count; i++)
{
Add(column[i].ColumnName, column[i].ValueType.FullName);
}
AddBr();
}
rowCount = 0;//重置为0
}
///
/// Fill obj and get json from ToString() method
/// 可从类(对象,泛型List、泛型Dictionary)中填充,最终可输出json字符串。
///
/// 实体类对象
public void Fill(object obj)
{
if (obj != null)
{
if (obj is String || obj is ValueType)
{
Fill(Convert.ToString(obj));
}
else if (obj is DataTable)
{
MDataTable dt = obj as DataTable;
Fill(dt);
}
else if (obj is DataRow)
{
MDataRow row = obj as DataRow;
Fill(row);
}
else if (obj is MDataTable)
{
Fill(obj as MDataTable);
}
else if (obj is MDataRow)
{
Fill(obj as MDataRow);
}
else if (obj is DataRowCollection)
{
MDataTable dt = (MDataRowCollection)obj;
Fill(dt);
}
else if (obj is MDataRowCollection)
{
MDataTable dt = (MDataRowCollection)obj;
Fill(dt);
}
else if (obj is DataColumnCollection)
{
MDataColumn mdc = obj as DataColumnCollection;
Fill(mdc, true);
}
else if (obj is Dictionary)
{
Fill(obj as Dictionary);//避开转Row,提升性能
}
else if (obj is MDictionary)
{
Fill(obj as MDictionary);//避开转Row,提升性能
}
else if (obj is Dictionary)
{
Fill(obj as Dictionary);//避开转Row,提升性能
}
else if (obj is MDictionary)
{
Fill(obj as MDictionary);//避开转Row,提升性能
}
else if (obj is IEnumerable)
{
#region IEnumerable
Type t = obj.GetType();
Type[] argTypes;
int len = ReflectTool.GetArgumentLength(ref t, out argTypes);
if (len == 1)
{
foreach (object o in obj as IEnumerable)
{
if (o is MDataTable)
{
Fill(o as MDataTable);
}
else if (o is DataTable)
{
MDataTable dt = o as DataTable;
Fill(dt);
}
else if (o is String || o is DateTime || o is Enum || o is Guid)
{
string str = o.ToString();
if (str.Length > 0 && (str[0] == '{' || str[0] == '[') && JsonSplit.IsJson(str))
{
Fill(MDataRow.CreateFrom(o));
}
else
{
if (o is String) { SetEscape(ref str); }
bodyItems.Add("\"" + str + "\"");
}
}
else if (o is ValueType)
{
bodyItems.Add(o.ToString());
}
else if (o is MDataRow)
{
Fill(o as MDataRow);
}
else
{
Type listType = argTypes[0];
if (ReflectTool.GetSystemType(ref listType) == SysType.Custom)
{
FillEntity(o);
}
else
{
Fill(MDataRow.CreateFrom(o));//直接优化成实体。
}
}
}
}
else if (len == 2)
{
if (t.Name.StartsWith("MDictionary") && argTypes[0].Name == "String")
{
List items = t.GetMethod("GetKeys").Invoke(obj, new object[0]) as List;
IEnumerable values = t.GetMethod("GetValues").Invoke(obj, new object[0]) as IEnumerable;
int i = 0;
foreach (object value in values)
{
Add(items[i], value);
i++;
}
//MethodInfo methodGet = t.GetMethod("Get");
//foreach (var item in items)
//{
// Add(item, methodGet.Invoke(obj, new object[] { item }));
//}
}
else if (t.Name.StartsWith("Dictionary") && argTypes[0].Name == "String")
{
IEnumerable keys = t.GetProperty("Keys").GetValue(obj, null) as IEnumerable;
IEnumerable values = t.GetProperty("Values").GetValue(obj, null) as IEnumerable;
List items = new List();
foreach (string key in keys)
{
items.Add(key);
}
int i = 0;
foreach (object value in values)
{
Add(items[i], value);
i++;
}
}
else
{
Fill(MDataRow.CreateFrom(obj, t));
}
}
#endregion
}
else
{
FillEntity(obj);
}
}
}
public void Fill(string query)
{
if (!string.IsNullOrEmpty(query))
{
query = query.Trim('?');
string[] items = query.Split('&');
foreach (string item in items)
{
if (!string.IsNullOrEmpty(item))
{
int index = item.IndexOf('=');
if (index > -1)
{
Add(item.Substring(0, index), item.Substring(index + 1, item.Length - index - 1));
}
else
{
Add(item, "");
}
}
}
}
}
public void Fill(Dictionary dic)
{
foreach (var item in dic)
{
Add(item.Key, item.Value);
}
}
public void Fill(MDictionary dic)
{
List items = dic.GetKeys();
foreach (var item in items)
{
Add(item, dic[item]);
}
}
public void Fill(Dictionary dic)
{
foreach (var item in dic)
{
Add(item.Key, item.Value);
}
}
public void Fill(MDictionary dic)
{
List items = dic.GetKeys();
foreach (var item in items)
{
Add(item, dic[item]);
}
}
///
/// 加载实体
///
///
private void FillEntity(object entity)
{
Type t = entity.GetType();
List pList = ReflectTool.GetPropertyList(t);
if (pList.Count > 0)
{
foreach (PropertyInfo item in pList)
{
SetJson(entity, item, null);
}
}
List fList = ReflectTool.GetFieldList(t);
if (fList.Count > 0)
{
foreach (FieldInfo item in fList)
{
SetJson(entity, null, item);
}
}
AddBr();
}
private void SetJson(object entity, PropertyInfo pi, FieldInfo fi)
{
if (ReflectTool.ExistsAttr(AppConst.JsonIgnoreType, pi, fi))//获取Json忽略标识
{
return;//被Json忽略的列,不在返回列结构中。
}
string name = pi != null ? pi.Name : fi.Name;
object objValue = pi != null ? pi.GetValue(entity, null) : fi.GetValue(entity);
Type type = pi != null ? pi.PropertyType : fi.FieldType;
string dateFormat = DateTimeFormatter;
if (type.IsEnum)
{
if (ReflectTool.ExistsAttr(AppConst.JsonEnumToStringType, pi, fi))
{
objValue = objValue.ToString();
type = typeof(String);
}
else if (ReflectTool.ExistsAttr(AppConst.JsonEnumToDescriptionType, pi, fi))
{
FieldInfo field = type.GetField(objValue.ToString());
if (field != null)
{
DescriptionAttribute da = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
if (da != null)
{
objValue = da.Description;
type = typeof(String);
}
}
}
else
{
objValue = (int)objValue;
}
}
else if (type.FullName.Contains("System.DateTime") && ReflectTool.ExistsAttr(AppConst.JsonFormatType, pi, fi))
{
JsonFormatAttribute jf = ReflectTool.GetAttr(pi, fi);
if (jf != null)
{
dateFormat = jf.DatetimeFormat;
}
}
SetNameValue(name, objValue, type, dateFormat);
}
private void SetNameValue(string name, object objValue, Type valueType, string dateFormat)
{
if (IsConvertNameToLower)
{
name = name.ToLower();
}
string value = null;
bool noQuot = false;
if (objValue == null || objValue == DBNull.Value)
{
if (_RowOp == Table.RowOp.IgnoreNull)
{
return;
}
value = "null";
noQuot = true;
}
else
{
if (valueType.FullName == "System.Object")
{
valueType = objValue.GetType();//定位到指定类型。
}
value = Convert.ToString(objValue);
DataGroupType group = DataType.GetGroup(DataType.GetSqlType(valueType));
noQuot = group == DataGroupType.Number || group == DataGroupType.Bool;
#region 处理非Null的情况
if (group == DataGroupType.Bool) // oracle 下的number 1会处理成bool类型
{
value = value.ToLower();
}
else if (group == DataGroupType.Date)
{
DateTime dt;
if (DateTime.TryParse(value, out dt))
{
value = dt.ToString(dateFormat);
}
}
else if (group == DataGroupType.Object)
{
#region 处理对象及循环引用。
int hash = objValue.GetHashCode();
//检测是否循环引用
if (LoopCheckList.ContainsKey(hash))
{
//continue;
int level = LoopCheckList[hash];
if (level < Level)
{
return;
}
else
{
LoopCheckList[hash] = Level;//更新级别
}
}
else
{
LoopCheckList.Add(hash, Level);
}
if (valueType.Name == "Byte[]")
{
value = Convert.ToBase64String(objValue as byte[]);
}
else
{
JsonHelper js = new JsonHelper(false, false);
js.Level = Level + 1;
js.LoopCheckList = LoopCheckList;
js.Escape = Escape;
js._RowOp = _RowOp;
js.DateTimeFormatter = dateFormat;
js.IsConvertNameToLower = IsConvertNameToLower;
js.Fill(objValue);
value = js.ToString(objValue is IList || objValue is MDataTable || objValue is DataTable);
noQuot = true;
//if (objValue is IEnumerable)
//{
// int len = ReflectTool.GetArgumentLength(ref valueType);
// if (len <= 1)//List
// {
// JsonHelper js = new JsonHelper(false, false);
// js.Level = Level + 1;
// js.LoopCheckList = LoopCheckList;
// js.Escape = Escape;
// js._RowOp = _RowOp;
// js.DateTimeFormatter = dateFormat;
// js.IsConvertNameToLower = IsConvertNameToLower;
// if (objValue is MDataRowCollection)
// {
// MDataTable dtx = (MDataRowCollection)objValue;
// js.Fill(dtx);
// }
// else
// {
// js.Fill(objValue);
// }
// value = js.ToString(true);
// noQuot = true;
// }
// else if (len == 2)//Dictionary
// {
// MDataRow dicRow = MDataRow.CreateFrom(objValue);
// dicRow.DynamicData = LoopCheckList;
// value = dicRow.ToJson(RowOp, IsConvertNameToLower, Escape);
// noQuot = true;
// }
//}
//else
//{
// if (!valueType.FullName.StartsWith("System."))//普通对象。
// {
// MDataRow oRow = new MDataRow(TableSchema.GetColumnByType(valueType));
// oRow.DynamicData = LoopCheckList;
// oRow.LoadFrom(objValue);
// value = oRow.ToJson(RowOp, IsConvertNameToLower, Escape);
// noQuot = true;
// }
// else if (valueType.FullName == "System.Data.DataTable")
// {
// MDataTable dt = objValue as DataTable;
// dt.DynamicData = LoopCheckList;
// value = dt.ToJson(false, false, RowOp, IsConvertNameToLower, Escape);
// noQuot = true;
// }
//}
}
#endregion
}
#endregion
}
Add(name, value, noQuot);
}
private static Dictionary lockList = new Dictionary();
///
/// 从Json字符串中反加载成数据表
///
internal static MDataTable ToMDataTable(string jsonOrFileName, MDataColumn mdc, EscapeOp op)
{
MDataTable table = new MDataTable();
if (mdc != null)
{
table.Columns = mdc;
}
if (string.IsNullOrEmpty(jsonOrFileName))
{
return table;
}
else
{
jsonOrFileName = jsonOrFileName.Trim();
}
try
{
#region 读取Json
string json = string.Empty;
#region 获取Json字符串
if (!jsonOrFileName.StartsWith("{") && !jsonOrFileName.StartsWith("["))//读取文件。
{
if (System.IO.File.Exists(jsonOrFileName))
{
table.TableName = Path.GetFileNameWithoutExtension(jsonOrFileName);
if (table.Columns.Count == 0)
{
table.Columns = MDataColumn.CreateFrom(jsonOrFileName, false);
}
json = IOHelper.ReadAllText(jsonOrFileName).Trim(',', ' ', '\r', '\n');
}
}
else
{
json = jsonOrFileName;
}
if (json.StartsWith("{"))
{
json = '[' + json + ']';
}
#endregion
List> result = SplitArray(json);
if (result != null && result.Count > 0)
{
#region 加载数据
if (result.Count == 1)
{
#region 自定义输出头判断
Dictionary dic = result[0];
if (dic.ContainsKey("total") && dic.ContainsKey("rows"))
{
int count = 0;
if (int.TryParse(dic["total"], out count))
{
table.RecordsAffected = count;//还原记录总数。
}
result = SplitArray(dic["rows"]);
}
else if (dic.ContainsKey("TableName") && dic.ContainsKey("Columns"))
{
table.TableName = dic["TableName"];
if (dic.ContainsKey("Description"))
{
table.Description = dic["Description"];
}
if (dic.ContainsKey("RelationTables"))
{
table.Columns.AddRelateionTableName(dic["RelationTables"]);
}
result = SplitArray(dic["Columns"]);
}
#endregion
}
if (result != null && result.Count > 0)
{
Dictionary keyValueDic = null;
for (int i = 0; i < result.Count; i++)
{
keyValueDic = result[i];
if (i == 0)
{
#region 首行列头检测
bool addColumn = table.Columns.Count == 0;
bool isContinue = false;
int k = 0;
foreach (KeyValuePair item in keyValueDic)
{
if (k == 0 && item.Value.StartsWith("System."))
{
isContinue = true;
}
if (!addColumn)
{
break;
}
if (!table.Columns.Contains(item.Key))
{
SqlDbType type = SqlDbType.NVarChar;
if (isContinue && item.Value.StartsWith("System."))//首行是表结构
{
type = DataType.GetSqlType(item.Value.Replace("System.", string.Empty));
}
table.Columns.Add(item.Key, type, (k == 0 && type == SqlDbType.Int));
if (k > keyValueDic.Count - 3 && type == SqlDbType.DateTime)
{
table.Columns[k].DefaultValue = SqlValue.GetDate;
}
}
k++;
}
if (isContinue)
{
continue;
}
#endregion
}
bool isKeyValue = table.Columns.Count == 2 && table.Columns[1].ColumnName == "Value" && (table.Columns[0].ColumnName == "Key" || table.Columns[0].ColumnName == "Name");
if (isKeyValue)
{
foreach (KeyValuePair item in keyValueDic)
{
MDataRow row = table.NewRow(true);
row.Set(0, item.Key);
row.Set(1, item.Value);
}
}
else
{
MDataRow row = table.NewRow(true);
MDataCell cell = null;
foreach (KeyValuePair item in keyValueDic)
{
cell = row[item.Key];
if (cell == null && mdc == null)
{
table.Columns.Add(item.Key, SqlDbType.NVarChar);
cell = row[item.Key];
}
if (cell != null)
{
string val = UnEscape(item.Value, op);
cell.Value = val;
cell.State = 1;
}
}
}
}
}
#endregion
}
else
{
List items = JsonSplit.SplitEscapeArray(json);
if (items != null && items.Count > 0)
{
if (mdc == null)
{
table.Columns.Add("Key");
}
foreach (string item in items)
{
table.NewRow(true).Set(0, item.Trim('"', '\''));
}
}
}
#endregion
}
catch (Exception err)
{
Log.Write(err, LogType.Error);
}
return table;
}
///
/// 将Json转换成集合
///
/// 集合类型
/// json数据
///
///
private static T ToIEnumerator(string json, EscapeOp op)
where T : class
{
return ToIEnumerator(typeof(T), json, op) as T;
}
private static object ToIEnumerator(Type t, string json, EscapeOp op)
{
if (t.FullName.StartsWith("System.Collections.") || t.FullName.Contains("MDictionary") || t.FullName.Contains("MList"))
{
Type[] ts;
int argLength = ReflectTool.GetArgumentLength(ref t, out ts);
if (argLength == 1)
{
return JsonSplit.ToEntityOrList(t, json, op);
}
else
{
#region Dictionary
if (t.Name.StartsWith("Dictionary") && ts[0].Name == "String" && ts[1].Name == "String")
{
//忽略MDictionary
return Split(json);
}
object objT = t.Name.Contains("Dictionary") ? Activator.CreateInstance(t, StringComparer.OrdinalIgnoreCase) : Activator.CreateInstance(t);
Type oT = objT.GetType();
MethodInfo mi = null;
try
{
if (t.Name == "NameValueCollection")
{
mi = oT.GetMethod("Add", new Type[] { typeof(string), typeof(string) });
}
else
{
mi = oT.GetMethod("Add");
}
}
catch
{
}
if (mi == null)
{
mi = oT.GetMethod("Add", new Type[] { typeof(string), typeof(string) });
}
if (mi != null)
{
Dictionary dic = Split(json);
if (dic != null && dic.Count > 0)
{
foreach (KeyValuePair kv in dic)
{
mi.Invoke(objT, new object[] { ConvertTool.ChangeType(kv.Key, ts[0]), ConvertTool.ChangeType(UnEscape(kv.Value, op), ts[1]) });
}
}
return objT;
}
#endregion
}
}
else if (t.FullName.EndsWith("[]"))
{
return new MDataRow().GetObj(t, json);
}
return null;
}
public static T ToEntity(string json) where T : class
{
return ToEntity(json, DefaultEscape);
}
internal static object ToEntity(Type t, string json, EscapeOp op)
{
if (t.FullName == "System.Data.DataTable")
{
return MDataTable.CreateFrom(json, null, op).ToDataTable();
}
if (t.Name == "MDataTable")
{
return MDataTable.CreateFrom(json, null, op);
}
if (t.FullName.StartsWith("System.Collections.") || t.FullName.EndsWith("[]") || t.FullName.Contains("MDictionary") || t.FullName.Contains("MList"))
{
return ToIEnumerator(t, json, op);
}
else
{
return JsonSplit.ToEntityOrList(t, json, op);
}
}
///
/// Convert json to Entity
/// 将Json转换为实体
///
/// Type类型
public static T ToEntity(string json, EscapeOp op) where T : class
{
Type t = typeof(T);
if (t.FullName == "System.Data.DataTable")
{
object dt = MDataTable.CreateFrom(json, null, op).ToDataTable();
return (T)dt;
}
if (t.Name == "MDataTable")
{
object mdt = MDataTable.CreateFrom(json, null, op);
return (T)mdt;
}
if (t.FullName.StartsWith("System.Collections.") || t.FullName.EndsWith("[]") || t.FullName.Contains("MDictionary") || t.FullName.Contains("MList"))
{
return ToIEnumerator(json, op);
}
else
{
return JsonSplit.ToEntity(json, op);
}
}
public static List ToList(string json)// where T : class
{
return ToList(json, DefaultEscape);
}
///
/// Convert json to Entity List
/// 将Json转换为实体列表
///
/// Type类型
public static List ToList(string json, EscapeOp op)// where T : class
{
return JsonSplit.ToList(json, 0, op);//减少中间转换环节。
}
///
/// Convert object to json
/// 将一个对象(实体,泛型List,字典Dictionary)转成Json
///
public static string ToJson(object obj)
{
return ToJson(obj, false, RowOp.IgnoreNull);
}
public static string ToJson(object obj, bool isConvertNameToLower)
{
return ToJson(obj, isConvertNameToLower, RowOp.IgnoreNull);
}
public static string ToJson(object obj, bool isConvertNameToLower, RowOp rowOp)
{
return ToJson(obj, isConvertNameToLower, rowOp, DefaultEscape);
}
/// default value is RowOp.All
/// 默认值为RowOp.All
public static string ToJson(object obj, bool isConvertNameToLower, RowOp rowOp, EscapeOp escapeOp)
{
string text = Convert.ToString(obj);
if (text == "")
{
return "{}";
}
else if (text[0] == '{' || text[0] == '[')
{
if (IsJson(text))
{
return text;
}
}
else if (text[0] == '<' && text[text.Length - 1] == '>')
{
return XmlToJson(text, true);
}
JsonHelper js = new JsonHelper();
js.LoopCheckList.Add(obj.GetHashCode(), 0);
js.Escape = escapeOp;
js.IsConvertNameToLower = isConvertNameToLower;
js.RowOp = rowOp;
js.Fill(obj);
return js.ToString(obj is IList || obj is DataTable || obj is MDataTable);
}
}
public partial class JsonHelper
{
#region Xml 转 Json
///
/// 转Json
/// xml字符串
/// 是否将属性值也输出
///
private static string XmlToJson(string xml, bool isWithAttr)
{
using (XHtmlAction action = new XHtmlAction(false, true))
{
try
{
action.LoadXml(xml);
return action.ToJson(action.XmlDoc.DocumentElement, isWithAttr);
}
catch (Exception err)
{
Log.WriteLogToTxt(err, LogType.Error);
return string.Empty;
}
}
}
#endregion
#region Json 转 Xml
///
/// Convert json to Xml
/// 将一个Json转成Xml
///
public static string ToXml(string json)
{
return ToXml(json, true);
}
public static string ToXml(string json, bool isWithAttr)
{
return ToXml(json, isWithAttr, DefaultEscape);
}
public static string ToXml(string json, bool isWithAttr, EscapeOp op)
{
return ToXml(json, isWithAttr, op, null);
}
/// default value is true
/// 是否转成属性,默认true
public static string ToXml(string json, bool isWithAttr, EscapeOp op, string rootName)
{
if (!string.IsNullOrEmpty(rootName))
{
json = string.Format("{{\"{0}\":{1}}}", rootName, json);
}
StringBuilder xml = new StringBuilder();
xml.Append("");
List> dicList = JsonSplit.Split(json);
if (dicList != null && dicList.Count > 0)
{
bool addRoot = dicList.Count > 1 || dicList[0].Count > 1;
if (addRoot)
{
xml.Append(string.Format("<{0}>", rootName ?? "root"));//";
}
xml.Append(GetXmlList(dicList, isWithAttr, op));
if (addRoot)
{
xml.Append(string.Format("{0}>", rootName ?? "root"));//";
}
}
return xml.ToString();
}
private static string GetXmlList(List> dicList, bool isWithAttr, EscapeOp op)
{
if (dicList == null || dicList.Count == 0)
{
return string.Empty;
}
StringBuilder xml = new StringBuilder();
for (int i = 0; i < dicList.Count; i++)
{
xml.Append(GetXml(dicList[i], isWithAttr, op));
}
return xml.ToString();
}
private static string GetXml(Dictionary dic, bool isWithAttr, EscapeOp op)
{
StringBuilder xml = new StringBuilder();
bool isJson = false;
foreach (KeyValuePair item in dic)
{
isJson = IsJson(item.Value);
if (!isJson)
{
xml.AppendFormat("<{0}>{1}{0}>", item.Key, FormatCDATA(UnEscape(item.Value, op)));
}
else
{
string key = item.Key;
if (key.EndsWith("List") && isWithAttr)
{
xml.AppendFormat("<{0}>", key);
key = key.Substring(0, key.Length - 4);
}
List> jsonList = JsonSplit.Split(item.Value);
if (jsonList != null && jsonList.Count > 0)
{
if (!isWithAttr)
{
xml.AppendFormat("<{0}>", item.Key);
}
for (int j = 0; j < jsonList.Count; j++)
{
if (isWithAttr)
{
xml.Append(GetXmlElement(key, jsonList[j], op));
}
else
{
xml.Append(GetXml(jsonList[j], isWithAttr, op));
}
}
if (!isWithAttr)
{
xml.AppendFormat("{0}>", key);
}
}
else // 空Json {}
{
xml.AppendFormat("<{0}>{0}>", key);
}
if (item.Key.EndsWith("List") && isWithAttr)
{
xml.AppendFormat("{0}>", item.Key);
}
}
}
return xml.ToString();
}
private static string GetXmlElement(string parentName, Dictionary dic, EscapeOp op)
{
StringBuilder xml = new StringBuilder();
Dictionary jsonDic = new Dictionary(StringComparer.OrdinalIgnoreCase);
xml.Append("<" + parentName);
foreach (KeyValuePair kv in dic)
{
if (kv.Value.IndexOf('"') > -1 || kv.Value.Length > 50
|| kv.Key.Contains("Remark") || kv.Key.Contains("Description") || kv.Key.Contains("Rule")
|| IsJson(kv.Value)) // 属性不能带双引号,所以转到元素处理。
{
jsonDic.Add(kv.Key, kv.Value);
}
}
//InnerText 节点存在=》(如果有元素节点,则当属性处理;若无,则当InnerText)
bool useForInnerText = dic.ContainsKey(parentName) && jsonDic.Count == 0;
foreach (KeyValuePair kv in dic)
{
if (!jsonDic.ContainsKey(kv.Key) && (kv.Key != parentName || !useForInnerText))
{
xml.AppendFormat(" {0}=\"{1}\"", kv.Key, kv.Value);//先忽略同名属性,内部InnerText节点,
}
}
xml.Append(">");
if (useForInnerText)
{
xml.Append(FormatCDATA(UnEscape(dic[parentName], op)));//InnerText。
}
else if (jsonDic.Count > 0)
{
xml.Append(GetXml(jsonDic, true, op));//数组,当元素处理。
}
xml.Append("" + parentName + ">");
return xml.ToString();
}
private static string FormatCDATA(string text)
{
if (text.LastIndexOfAny(new char[] { '<', '>', '&' }) > -1 && !text.StartsWith("";
}
return text;
}
#endregion
}
public partial class JsonHelper
{
///
/// 读取文本中的Json(并去掉注释)
///
///
internal static string ReadJson(string filePath)
{
string json = IOHelper.ReadAllText(filePath);
if (!string.IsNullOrEmpty(json))
{
int index = json.LastIndexOf("/*");
if (index > -1)//去掉注释
{
json = Regex.Replace(json, @"/\*[^:][.\s\S]*?\*/", string.Empty, RegexOptions.IgnoreCase);
}
char splitChar = '\n';
if (json.IndexOf(splitChar) > -1)
{
string[] items = json.Split(splitChar);
StringBuilder sb = new StringBuilder();
foreach (string item in items)
{
if (!item.TrimStart(' ', '\r', '\t').StartsWith("//"))
{
sb.Append(item.Trim(' ', '\r', '\t'));
}
}
json = sb.ToString();
}
if (json.IndexOf("\\\\") > -1)
{
json = json.Replace("\\\\", "\\");
}
}
return json;
}
}
}