From 23c9ade79ec8566818c5eceebf0c63fbb1f28932 Mon Sep 17 00:00:00 2001
From: milimoe <110188673+milimoe@users.noreply.github.com>
Date: Sat, 3 Jun 2023 18:57:24 +0800
Subject: [PATCH] =?UTF-8?q?=E6=8B=A5=E6=8A=B1System.Text.Json=20(#27)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* 添加适用于DataSet和DateTime的JSON自定义转换器。
* 添加JsonManager,删除JsonObject并仅使用SocketObject
* 移除Newtonsoft.Json引用
---
Api/Utility/General.cs | 23 +-
FunGame.Core.csproj | 4 -
.../Common/JsonConverter/DataSetConverter.cs | 302 ++++++++++++++++++
.../Common/JsonConverter/DateTimeConverter.cs | 31 ++
Library/Common/Network/ClientSocket.cs | 2 +-
Library/Common/Network/JsonObject.cs | 67 ----
Library/Common/Network/Socket.cs | 2 +-
Library/Common/Network/SocketObject.cs | 49 ++-
Library/Constant/General.cs | 5 +-
Service/JsonManager.cs | 88 +++++
Service/SocketManager.cs | 36 +--
11 files changed, 492 insertions(+), 117 deletions(-)
create mode 100644 Library/Common/JsonConverter/DataSetConverter.cs
create mode 100644 Library/Common/JsonConverter/DateTimeConverter.cs
delete mode 100644 Library/Common/Network/JsonObject.cs
create mode 100644 Service/JsonManager.cs
diff --git a/Api/Utility/General.cs b/Api/Utility/General.cs
index 8f44926..7b7851b 100644
--- a/Api/Utility/General.cs
+++ b/Api/Utility/General.cs
@@ -1,6 +1,5 @@
using System.Net.NetworkInformation;
using System.Security.Cryptography;
-using System.Text.Json;
using System.Text.RegularExpressions;
using Milimoe.FunGame.Core.Library.Constant;
@@ -115,6 +114,28 @@ namespace Milimoe.FunGame.Core.Api.Utility
}
return -1;
}
+
+ ///
+ /// 返回目标对象的Json字符串
+ ///
+ ///
+ ///
+ ///
+ public static string JsonSerialize(T obj)
+ {
+ return Service.JsonManager.GetString(obj);
+ }
+
+ ///
+ /// 反序列化Json对象
+ ///
+ ///
+ ///
+ ///
+ public static T? JsonDeserialize(string json)
+ {
+ return Service.JsonManager.GetObject(json);
+ }
}
#endregion
diff --git a/FunGame.Core.csproj b/FunGame.Core.csproj
index fbfc64c..fd949d3 100644
--- a/FunGame.Core.csproj
+++ b/FunGame.Core.csproj
@@ -24,8 +24,4 @@
embedded
-
-
-
-
diff --git a/Library/Common/JsonConverter/DataSetConverter.cs b/Library/Common/JsonConverter/DataSetConverter.cs
new file mode 100644
index 0000000..1716742
--- /dev/null
+++ b/Library/Common/JsonConverter/DataSetConverter.cs
@@ -0,0 +1,302 @@
+using System.Data;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Milimoe.FunGame.Core.Library.Constant;
+using Milimoe.FunGame.Core.Service;
+
+namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
+{
+ public class DataSetConverter : JsonConverter
+ {
+ public override DataSet Read(ref Utf8JsonReader reader, Type type, JsonSerializerOptions options)
+ {
+ DataSet ds = new();
+ DataTable dt = new();
+
+ while (reader.Read())
+ {
+ if (reader.TokenType == JsonTokenType.PropertyName)
+ {
+ string property = reader.GetString() ?? "";
+
+ switch (property)
+ {
+ case "TableName":
+ reader.Read();
+ string tableName = reader.GetString() ?? "";
+ dt = new DataTable(tableName);
+ ds.Tables.Add(dt);
+ break;
+
+ case "Columns":
+ reader.Read();
+ ReadColumns(reader, dt);
+ break;
+
+ case "Rows":
+ reader.Read();
+ ReadRows(reader, dt);
+ break;
+ }
+ }
+ }
+
+ return ds;
+ }
+
+ public override void Write(Utf8JsonWriter writer, DataSet value, JsonSerializerOptions options)
+ {
+ writer.WriteStartObject();
+
+ writer.WriteString("TableName", value.Tables[0].TableName);
+
+ writer.WritePropertyName("Columns");
+ writer.WriteStartArray();
+
+ foreach (DataColumn column in value.Tables[0].Columns)
+ {
+ writer.WriteStartObject();
+
+ writer.WriteString("ColumnName", column.ColumnName);
+ writer.WriteString("DataType", column.DataType.FullName);
+
+ writer.WriteEndObject();
+ }
+
+ writer.WriteEndArray();
+
+ writer.WritePropertyName("Rows");
+ writer.WriteStartArray();
+
+ foreach (DataRow row in value.Tables[0].Rows)
+ {
+ writer.WriteStartArray();
+
+ for (int i = 0; i < value.Tables[0].Columns.Count; i++)
+ {
+ object? rowValue = row[i];
+
+ switch (value.Tables[0].Columns[i].DataType.FullName)
+ {
+ case "System.Boolean":
+ writer.WriteBooleanValue((bool)rowValue);
+ break;
+
+ case "System.Byte":
+ writer.WriteNumberValue((byte)rowValue);
+ break;
+
+ case "System.Char":
+ writer.WriteStringValue(value.ToString());
+ break;
+
+ case "System.DateTime":
+ writer.WriteStringValue(((DateTime)rowValue).ToString(General.GeneralDateTimeFormat));
+ break;
+
+ case "System.Decimal":
+ writer.WriteNumberValue((decimal)rowValue);
+ break;
+
+ case "System.Double":
+ writer.WriteNumberValue((double)rowValue);
+ break;
+
+ case "System.Guid":
+ writer.WriteStringValue(value.ToString());
+ break;
+
+ case "System.Int16":
+ writer.WriteNumberValue((short)rowValue);
+ break;
+
+ case "System.Int32":
+ writer.WriteNumberValue((int)rowValue);
+ break;
+
+ case "System.Int64":
+ writer.WriteNumberValue((long)rowValue);
+ break;
+
+ case "System.SByte":
+ writer.WriteNumberValue((sbyte)rowValue);
+ break;
+
+ case "System.Single":
+ writer.WriteNumberValue((float)rowValue);
+ break;
+
+ case "System.String":
+ writer.WriteStringValue((string)rowValue);
+ break;
+
+ case "System.UInt16":
+ writer.WriteNumberValue((ushort)rowValue);
+ break;
+
+ case "System.UInt32":
+ writer.WriteNumberValue((uint)rowValue);
+ break;
+
+ case "System.UInt64":
+ writer.WriteNumberValue((ulong)rowValue);
+ break;
+ }
+ }
+
+ writer.WriteEndArray();
+ }
+
+ writer.WriteEndArray();
+
+ writer.WriteEndObject();
+ }
+
+ #pragma warning disable CA1822 // 不需要设为静态
+ private void ReadColumns(Utf8JsonReader reader, DataTable dataTable)
+ #pragma warning restore CA1822 // 不需要设为静态
+ {
+ while (reader.Read())
+ {
+ if (reader.TokenType == JsonTokenType.EndArray)
+ {
+ break;
+ }
+
+ if (reader.TokenType == JsonTokenType.StartObject)
+ {
+ DataColumn column = new();
+
+ while (reader.Read())
+ {
+ if (reader.TokenType == JsonTokenType.PropertyName)
+ {
+ string propertyName = reader.GetString() ?? "";
+
+ switch (propertyName)
+ {
+ case "ColumnName":
+ reader.Read();
+ column.ColumnName = reader.GetString();
+ break;
+
+ case "DataType":
+ reader.Read();
+ Type dataType = Type.GetType(reader.GetString() ?? "") ?? typeof(object);
+ column.DataType = dataType;
+ break;
+ }
+ }
+
+ if (reader.TokenType == JsonTokenType.EndObject)
+ {
+ break;
+ }
+ }
+
+ dataTable.Columns.Add(column);
+ }
+ }
+ }
+
+ private void ReadRows(Utf8JsonReader reader, DataTable dataTable)
+ {
+ object[] values = new object[dataTable.Columns.Count];
+
+ while (reader.Read())
+ {
+ if (reader.TokenType == JsonTokenType.EndArray)
+ {
+ break;
+ }
+
+ if (reader.TokenType == JsonTokenType.StartArray)
+ {
+ int index = 0;
+
+ while (reader.Read())
+ {
+ if (reader.TokenType == JsonTokenType.EndArray)
+ {
+ break;
+ }
+
+ switch (dataTable.Columns[index].DataType.ToString())
+ {
+ case "System.Boolean":
+ values[index] = reader.GetBoolean();
+ break;
+
+ case "System.Byte":
+ values[index] = reader.GetByte();
+ break;
+
+ case "System.Char":
+ values[index] = (reader.GetString() ?? "")[0];
+ break;
+
+ case "System.DateTime":
+ string dateString = reader.GetString() ?? "";
+ if (DateTime.TryParseExact(dateString, General.GeneralDateTimeFormat, null, System.Globalization.DateTimeStyles.None, out DateTime result))
+ {
+ values[index] = result;
+ }
+ values[index] = DateTime.MinValue;
+ break;
+
+ case "System.Decimal":
+ values[index] = reader.GetDecimal();
+ break;
+
+ case "System.Double":
+ values[index] = reader.GetDouble();
+ break;
+
+ case "System.Guid":
+ values[index] = Guid.Parse(reader.GetString() ?? Guid.Empty.ToString());
+ break;
+
+ case "System.Int16":
+ values[index] = reader.GetInt16();
+ break;
+
+ case "System.Int32":
+ values[index] = reader.GetInt32();
+ break;
+
+ case "System.Int64":
+ values[index] = reader.GetInt64();
+ break;
+
+ case "System.SByte":
+ values[index] = reader.GetSByte();
+ break;
+
+ case "System.Single":
+ values[index] = reader.GetSingle();
+ break;
+
+ case "System.String":
+ values[index] = reader.GetString() ?? "";
+ break;
+
+ case "System.UInt16":
+ values[index] = reader.GetUInt16();
+ break;
+
+ case "System.UInt32":
+ values[index] = reader.GetUInt32();
+ break;
+
+ case "System.UInt64":
+ values[index] = reader.GetUInt64();
+ break;
+ }
+ index++;
+ }
+ dataTable.Rows.Add(values);
+ }
+ }
+ }
+ }
+}
diff --git a/Library/Common/JsonConverter/DateTimeConverter.cs b/Library/Common/JsonConverter/DateTimeConverter.cs
new file mode 100644
index 0000000..db25b90
--- /dev/null
+++ b/Library/Common/JsonConverter/DateTimeConverter.cs
@@ -0,0 +1,31 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Milimoe.FunGame.Core.Library.Constant;
+
+namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
+{
+ public class DateTimeConverter : JsonConverter
+ {
+ public override DateTime Read(ref Utf8JsonReader reader, Type type, JsonSerializerOptions options)
+ {
+ if (reader.TokenType != JsonTokenType.String)
+ {
+ throw new JsonException();
+ }
+
+ string date = reader.GetString() ?? "";
+
+ if (DateTime.TryParseExact(date, General.GeneralDateTimeFormat, null, System.Globalization.DateTimeStyles.None, out DateTime result))
+ {
+ return result;
+ }
+
+ throw new JsonException();
+ }
+
+ public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
+ {
+ writer.WriteStringValue(value.ToString(General.GeneralDateTimeFormat));
+ }
+ }
+}
diff --git a/Library/Common/Network/ClientSocket.cs b/Library/Common/Network/ClientSocket.cs
index 8143681..22bf36d 100644
--- a/Library/Common/Network/ClientSocket.cs
+++ b/Library/Common/Network/ClientSocket.cs
@@ -66,7 +66,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
{
if (Instance != null)
{
- if (SocketManager.Send(Instance, type, Token, objs) == SocketResult.Success)
+ if (SocketManager.Send(Instance, new(type, Token, objs)) == SocketResult.Success)
{
return SocketResult.Success;
}
diff --git a/Library/Common/Network/JsonObject.cs b/Library/Common/Network/JsonObject.cs
deleted file mode 100644
index 9ac096b..0000000
--- a/Library/Common/Network/JsonObject.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using Milimoe.FunGame.Core.Library.Constant;
-
-namespace Milimoe.FunGame.Core.Library.Common.Network
-{
- [Serializable]
- public struct JsonObject
- {
- public SocketMessageType MessageType { get; } = SocketMessageType.Unknown;
- public Guid Token { get; }
- public object[] Parameters { get; }
- public string JsonString { get; }
-
- private JArray? JArray;
-
- public JsonObject(SocketMessageType MessageType, Guid Token, params object[] Parameters)
- {
- this.MessageType = MessageType;
- this.Token = Token;
- this.Parameters = Parameters;
- this.JsonString = JsonConvert.SerializeObject(this, Formatting.Indented);
- }
-
- public T? GetObject(int i)
- {
- if (i >= Parameters.Length) throw new IndexOutOfArrayLengthException();
- JArray ??= JArray.FromObject(Parameters);
- return JArray[i].ToObject();
- }
-
- public static string GetString(SocketMessageType MessageType, Guid Token, params object[] Parameters)
- {
- return new JsonObject(MessageType, Token, Parameters).JsonString;
- }
-
- public static JsonObject GetObject(string JsonString)
- {
- return JsonConvert.DeserializeObject(JsonString);
- }
-
- public static JsonObject[] GetObjects(string JsonString)
- {
- List jsons = new();
-
- JsonSerializer serializer = new();
- JsonTextReader reader = new(new StringReader(JsonString))
- {
- SupportMultipleContent = true
- };
-
- while (true)
- {
- if (!reader.Read())
- {
- break;
- }
-
- JsonObject json = serializer.Deserialize(reader);
-
- jsons.Add(json);
- }
-
- return jsons.ToArray();
- }
- }
-}
diff --git a/Library/Common/Network/Socket.cs b/Library/Common/Network/Socket.cs
index 45765e6..aa6ff59 100644
--- a/Library/Common/Network/Socket.cs
+++ b/Library/Common/Network/Socket.cs
@@ -45,7 +45,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
{
if (Instance != null)
{
- if (SocketManager.Send(type, Token, objs) == SocketResult.Success)
+ if (SocketManager.Send(new(type, Token, objs)) == SocketResult.Success)
{
return SocketResult.Success;
}
diff --git a/Library/Common/Network/SocketObject.cs b/Library/Common/Network/SocketObject.cs
index ddc6a11..bcb5fe9 100644
--- a/Library/Common/Network/SocketObject.cs
+++ b/Library/Common/Network/SocketObject.cs
@@ -1,4 +1,6 @@
-using Milimoe.FunGame.Core.Library.Constant;
+using System.Text.Json.Serialization;
+using Milimoe.FunGame.Core.Library.Constant;
+using Milimoe.FunGame.Core.Service;
namespace Milimoe.FunGame.Core.Library.Common.Network
{
@@ -8,34 +10,47 @@ namespace Milimoe.FunGame.Core.Library.Common.Network
public SocketMessageType SocketType { get; } = SocketMessageType.Unknown;
public Guid Token { get; } = Guid.Empty;
public object[] Parameters { get; } = Array.Empty