refactor: ♻️ 移除Newtonsoft.Json包 (#186)

Co-authored-by: tk <fiyne1a@dingtalk.com>
This commit is contained in:
nsnail 2024-11-04 16:18:47 +08:00 committed by GitHub
parent 13ba536df2
commit e71661663f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 113 additions and 19 deletions

View File

@ -4,7 +4,6 @@
[![.NET](https://github.com/nsnail/NetAdmin/actions/workflows/nightly-build.yml/badge.svg)](https://github.com/nsnail/NetAdmin/actions/workflows/nightly-build.yml)
[![MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/nsnail/NetAdmin/blob/main/LICENSE)
[![Furion](https://img.shields.io/badge/Furion-4.x-blueviolet.svg)](https://github.com/nsnail/NetAdmin/blob/main/LICENSE)
[![FreeSql](https://img.shields.io/badge/FreeSql-3.x-orange.svg)](https://github.com/nsnail/NetAdmin/blob/main/LICENSE)
## 在线预览
@ -86,7 +85,6 @@ XC-->XA
| 语言 | 集成领域 | 开源库 |
|------------|---------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| C# | Web基础框架 | [ASP.NET Core](https://github.com/dotnet/aspnetcore) |
| C# | 快速开发脚手架 | [Furion](https://gitee.com/dotnetchina/Furion) |
| C# | 数据库关系映射 | [FreeSql](https://github.com/dotnetcore/FreeSql) |
| C# | 代码质量检查 | [Roslynator.Analyzers](https://github.com/josefpihrt/roslynator) \| [SonarAnalyzer.CSharp](https://github.com/SonarSource/sonar-dotnet) \| [StyleCop.Analyzers](https://github.com/DotNetAnalyzers/StyleCopAnalyzers) |
| C# | 单元测试框架 | [xunit](https://github.com/xunit/xunit) \| [coverlet.collector](https://github.com/coverlet-coverage/coverlet) |

View File

@ -4,7 +4,7 @@
"ExecutionCron": "0 * * * * ?",
"HttpMethod": 3,
"JobName": "HTTP 请求测试",
"NextExecTime": "2020/9/13 12:26:40",
"NextExecTime": "2020-09-13 12:26:40",
"NextTimeId": 1600000000,
"RequestUrl": "https://httpbin.org/ip",
"Status": 1,

View File

@ -63,7 +63,7 @@ namespace NetAdmin.AdmServer.Host
.UseVueAdmin() // 托管管理后台,仅在非调试模式下
.UsePrometheus() // 使用Prometheus中间件启用HTTP性能监控
#endif
.UseInject(string.Empty) // 使用Inject中间件Furion脚手架的依赖注入支持
.UseInject(string.Empty) // 使用Inject中间件Gurion脚手架的依赖注入支持
.UseUnifyResultStatusCodes() // 使用UnifyResultStatusCodes中间件用于统一处理结果状态码
.UseCorsAccessor() // 使用CorsAccessor中间件启用跨域资源共享CORS支持
.UseRouting() // 使用Routing中间件配置路由映射

View File

@ -1,5 +1,4 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"Logging": {
"LogLevel": {
"Default": "Debug",

View File

@ -1,5 +1,4 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"Logging": {
"LogLevel": {
"Default": "Debug",

View File

@ -1,5 +1,4 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"Logging": {
"LogLevel": {
"Default": "Debug",

View File

@ -1,5 +1,4 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
// Swagger ------------------------------------------------------------------------------
"SpecificationDocumentSettings": {
"GroupOpenApiInfos": [

View File

@ -100,8 +100,8 @@ public abstract class RepositoryService<TEntity, TPrimary, TLogger>(BasicReposit
TEntity newValue //
, IEnumerable<string> includeFields //
, string[] excludeFields = null //
, Expression<Func<TEntity, bool>> whereExp = null //
, string whereSql = null //
, Expression<Func<TEntity, bool>> whereExp = null //
, string whereSql = null //
, bool ignoreVersion = false)
{
// 默认匹配主键

View File

@ -10,7 +10,6 @@
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.0-rc.2.24474.3"/>
<PackageReference Include="Minio" Version="6.0.3"/>
<PackageReference Include="NSExt" Version="2.2.0"/>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3"/>
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.4"/>
<PackageReference Include="System.Drawing.Common" Version="9.0.0-rc.2.24474.1"/>
</ItemGroup>

View File

@ -1,5 +1,4 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"AppSettings": {
"InjectSpecificationDocument": true,
"InjectMiniProfiler": true

View File

@ -1,5 +1,4 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"AppSettings": {
"InjectSpecificationDocument": true,
"InjectMiniProfiler": true

View File

@ -1,5 +1,4 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"AppSettings": {
"InjectSpecificationDocument": true,
"InjectMiniProfiler": true

View File

@ -1,5 +1,4 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
// App
"AppSettings": {
"InjectSpecificationDocument": false,

View File

@ -1,7 +1,6 @@
#if DBTYPE_SQLSERVER
using Microsoft.Data.SqlClient;
#endif
using Newtonsoft.Json;
using DataType = FreeSql.DataType;
namespace NetAdmin.Infrastructure.Utils;
@ -103,10 +102,18 @@ public sealed class FreeSqlBuilder(DatabaseOptions databaseOptions)
continue;
}
var fileContent = File.ReadAllText(file);
using var fs = File.OpenRead(file);
var jsonSerializerOptions = new JsonSerializerOptions(JsonSerializerOptions.Default) //
{
AllowTrailingCommas = true
, ReadCommentHandling = JsonCommentHandling.Skip
, TypeInfoResolver
= new DefaultJsonTypeInfoResolver { Modifiers = { JsonIgnoreRemover.RemoveJsonIgnore(entityType) } }
};
_ = jsonSerializerOptions.Converters.AddDateTimeTypeConverters();
dynamic entities = JsonConvert.DeserializeObject( //
fileContent, typeof(IEnumerable<>).MakeGenericType(entityType));
var jsonTypeInfo = JsonTypeInfo.CreateJsonTypeInfo(typeof(IEnumerable<>).MakeGenericType(entityType), jsonSerializerOptions);
var entities = JsonSerializer.Deserialize(fs, jsonTypeInfo);
// 如果表存在数据,跳过
var select = typeof(IFreeSql).GetMethod(nameof(freeSql.Select), 1, Type.EmptyTypes)?.MakeGenericMethod(entityType).Invoke(freeSql, null);

View File

@ -0,0 +1,98 @@
namespace NetAdmin.Infrastructure.Utils;
/// <summary>
/// 忽略 JsonIgnore 特性
/// </summary>
public static class JsonIgnoreRemover
{
private delegate TValue RefFunc<TObject, out TValue>(ref TObject arg);
/// <summary>
/// 忽略 JsonIgnore 特性
/// </summary>
public static Action<JsonTypeInfo> RemoveJsonIgnore(Type type)
{
return typeInfo => {
if (!type.IsAssignableFrom(typeInfo.Type) || typeInfo.Kind != JsonTypeInfoKind.Object) {
return;
}
foreach (var property in typeInfo.Properties.Where(property => property.ShouldSerialize != null &&
property.AttributeProvider?.IsDefined(typeof(JsonIgnoreAttribute), true) ==
true)) {
property.Get ??= CreatePropertyGetter(property);
property.Set ??= CreatePropertySetter(property);
if (property.Get != null) {
property.ShouldSerialize = null;
}
}
};
}
private static Func<object, object> CreateGetter(Type type, MethodInfo method)
{
if (method == null) {
return null;
}
#pragma warning disable S3011
var myMethod = typeof(JsonIgnoreRemover).GetMethod(nameof(CreateGetterGeneric), BindingFlags.NonPublic | BindingFlags.Static)!;
#pragma warning restore S3011
return (Func<object, object>)myMethod.MakeGenericMethod(type, method.ReturnType).Invoke(null, [method])!;
}
private static Func<object, object> CreateGetterGeneric<TObject, TValue>(MethodInfo method)
{
ArgumentNullException.ThrowIfNull(method);
if (typeof(TObject).IsValueType) {
var func = (RefFunc<TObject, TValue>)Delegate.CreateDelegate(typeof(RefFunc<TObject, TValue>), null, method);
return o => {
var tObj = (TObject)o;
return func(ref tObj);
};
}
else {
var func = (Func<TObject, TValue>)Delegate.CreateDelegate(typeof(Func<TObject, TValue>), method);
return o => func((TObject)o);
}
}
private static Func<object, object> CreatePropertyGetter(JsonPropertyInfo property)
{
return property.AttributeProvider as PropertyInfo is { ReflectedType: not null } info && info.GetGetMethod() is { } getMethod
? CreateGetter(info.ReflectedType, getMethod)
: null;
}
private static Action<object, object> CreatePropertySetter(JsonPropertyInfo property)
{
return property.AttributeProvider as PropertyInfo is { ReflectedType: not null } info && info.GetSetMethod() is { } setMethod
? CreateSetter(info.ReflectedType, setMethod)
: null;
}
private static Action<object, object> CreateSetter(Type type, MethodInfo method)
{
if (method == null) {
return null;
}
#pragma warning disable S3011
var myMethod = typeof(JsonIgnoreRemover).GetMethod(nameof(CreateSetterGeneric), BindingFlags.NonPublic | BindingFlags.Static)!;
#pragma warning restore S3011
return (Action<object, object>)myMethod.MakeGenericMethod(type, method.GetParameters().Single().ParameterType).Invoke(null, [method])!;
}
private static Action<object, object> CreateSetterGeneric<TObject, TValue>(MethodInfo method)
{
ArgumentNullException.ThrowIfNull(method);
if (typeof(TObject).IsValueType) {
return (o, v) => method.Invoke(o, [v]);
}
var func = (Action<TObject, TValue>)Delegate.CreateDelegate(typeof(Action<TObject, TValue>), method);
return (o, v) => func((TObject)o, (TValue)v);
}
}