using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Globalization;
using Microsoft.VisualBasic.CompilerServices;
using System.Data;
namespace MESws
{
///
/// 20210513 13871,Json相關擴充方法
///
internal static class JsonSerializationExceptionHelper
{
public static JsonSerializationException Create(this JsonReader reader, string format, params object[] args)
{
IJsonLineInfo lineInfo = reader as IJsonLineInfo;
string path = reader == null ? null : reader.Path;
string message = string.Format(CultureInfo.InvariantCulture, format, args);
if (Convert.ToBoolean(!message.EndsWith(Environment.NewLine, StringComparison.Ordinal)))
{
message = message.Trim();
if (Convert.ToBoolean(!message.EndsWith(".", StringComparison.Ordinal)))
message += ".";
message += " ";
}
message += string.Format(CultureInfo.InvariantCulture, "Path '{0}'", path);
if (lineInfo != null && lineInfo.HasLineInfo()) message += String.Format(CultureInfo.InvariantCulture, ", line {0}, position {1}", lineInfo.LineNumber, lineInfo.LinePosition);
message += ".";
return new JsonSerializationException(Convert.ToString(message));
}
}
internal static class StringUtils
{
public static string FormatWith(this string format, IFormatProvider provider, object arg0)
{
return format.FormatWith(provider, new[] { arg0 });
}
private static string FormatWith(string format, IFormatProvider provider, params object[] args)
{
return string.Format(provider, format, args);
}
}
internal static class JsonReaderExtensions
{
public static void ReadAndAssert(this JsonReader reader)
{
if (reader == null)
throw new ArgumentNullException("reader");
if (!reader.Read())
{
throw reader.Create("Unexpected end when reading JSON.");
}
}
}
///
/// 20210513 13871,Json DataTableConverter類別,自定義轉型方法,排除浮點數被轉成整數問題
///
internal class TypeInferringDataTableConverter : Newtonsoft.Json.Converters.DataTableConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
DataTable dt = existingValue as DataTable;
if (dt == null)
{
dt = objectType == typeof(DataTable) ? new DataTable() : (DataTable)Activator.CreateInstance(objectType);
}
if (reader.TokenType == JsonToken.PropertyName)
{
dt.TableName = Convert.ToString(reader.Value);
reader.ReadAndAssert();
if (reader.TokenType == JsonToken.Null)
{
return dt;
}
}
if (reader.TokenType != JsonToken.StartArray)
{
throw reader.Create("Unexpected JSON token when reading DataTable. Expected StartArray, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
reader.ReadAndAssert();
object ambiguousColumnTypes = new HashSet();
while (reader.TokenType != JsonToken.EndArray)
{
CreateRow(reader, dt, serializer, (HashSet)ambiguousColumnTypes);
reader.ReadAndAssert();
}
return dt;
}
private static void CreateRow(JsonReader reader, DataTable dt, JsonSerializer serializer, HashSet ambiguousColumnTypes)
{
var dr = dt.NewRow();
reader.ReadAndAssert();
while (reader.TokenType == JsonToken.PropertyName)
{
string columnName = Convert.ToString(reader.Value);
reader.ReadAndAssert();
DataColumn column = dt.Columns[columnName]; // 20211203 13871,DataTable內欄位如果是陣列、物件則不處理
if (column == null)
{
bool isAmbiguousType = false;
Type columnType = GetColumnDataType(reader, ref isAmbiguousType);
if (columnType == null) //20211203 13871,DataTable內欄位如果是陣列、物件則不處理
{
reader.ReadAndAssert();
continue;
}
column = new DataColumn(columnName, columnType);
dt.Columns.Add(column);
if (isAmbiguousType) ambiguousColumnTypes.Add(columnName);
}
else if (ambiguousColumnTypes.Contains(columnName))
{
bool isAmbiguousType = false;
Type newColumnType = GetColumnDataType(reader, ref isAmbiguousType);
if (!isAmbiguousType) ambiguousColumnTypes.Remove(columnName);
if (newColumnType != column.DataType)
{
column = ReplaceColumn(dt, column, newColumnType, serializer);
}
}
if (column.DataType == typeof(DataTable))
{
if (reader.TokenType == JsonToken.StartArray)
{
reader.ReadAndAssert();
}
var nestedDt = new DataTable();
object nestedUnknownColumnTypes = new HashSet();
while (reader.TokenType != JsonToken.EndArray)
{
CreateRow(reader, nestedDt, serializer, (HashSet)nestedUnknownColumnTypes);
reader.ReadAndAssert();
}
dr[columnName] = nestedDt;
}
else if (column.DataType.IsArray && column.DataType != typeof(byte[]))
{
if (reader.TokenType == JsonToken.StartArray)
{
reader.ReadAndAssert();
}
var o = new List