diff --git a/UIStandardWebApi.Entity/Class1.cs b/UIStandardWebApi.Entity/Class1.cs
new file mode 100644
index 0000000..eab2e5f
--- /dev/null
+++ b/UIStandardWebApi.Entity/Class1.cs
@@ -0,0 +1,7 @@
+namespace UIStandardWebApi.Entity
+{
+ public class Class1
+ {
+
+ }
+}
diff --git a/UIStandardWebApi.Entity/UIStandardWebApi.Entity.csproj b/UIStandardWebApi.Entity/UIStandardWebApi.Entity.csproj
new file mode 100644
index 0000000..fa71b7a
--- /dev/null
+++ b/UIStandardWebApi.Entity/UIStandardWebApi.Entity.csproj
@@ -0,0 +1,9 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/UIStandardWebApi.EntityDto/Class1.cs b/UIStandardWebApi.EntityDto/Class1.cs
new file mode 100644
index 0000000..c6413a9
--- /dev/null
+++ b/UIStandardWebApi.EntityDto/Class1.cs
@@ -0,0 +1,7 @@
+namespace UIStandardWebApi.EntityDto
+{
+ public class Class1
+ {
+
+ }
+}
diff --git a/UIStandardWebApi.EntityDto/UIStandardWebApi.EntityDto.csproj b/UIStandardWebApi.EntityDto/UIStandardWebApi.EntityDto.csproj
new file mode 100644
index 0000000..fa71b7a
--- /dev/null
+++ b/UIStandardWebApi.EntityDto/UIStandardWebApi.EntityDto.csproj
@@ -0,0 +1,9 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/UIStandardWebApi.WebCore/AutoMapExtend/AutoMapperConfigs.cs b/UIStandardWebApi.WebCore/AutoMapExtend/AutoMapperConfigs.cs
new file mode 100644
index 0000000..13d6a59
--- /dev/null
+++ b/UIStandardWebApi.WebCore/AutoMapExtend/AutoMapperConfigs.cs
@@ -0,0 +1,23 @@
+using AutoMapper;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace UIStandardWebApi.WebCore.AutoMapExtend
+{
+ ///
+ /// Dto映射配置
+ ///
+ public class AutoMapperConfigs : Profile
+ {
+ ///
+ /// 配置映射
+ ///
+ public AutoMapperConfigs()
+ {
+
+ }
+ }
+}
diff --git a/UIStandardWebApi.WebCore/CorsExtend/CorsExtension.cs b/UIStandardWebApi.WebCore/CorsExtend/CorsExtension.cs
new file mode 100644
index 0000000..3ff6c34
--- /dev/null
+++ b/UIStandardWebApi.WebCore/CorsExtend/CorsExtension.cs
@@ -0,0 +1,46 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace UIStandardWebApi.WebCore.CorsExtend
+{
+ ///
+ /// 跨域
+ ///
+ public static class CorsExtension
+ {
+
+ ///
+ /// 配置跨域策略
+ ///
+ ///
+ public static void AddCorsExt(this IServiceCollection services)
+ {
+ services.AddCors(options =>
+ {
+ // allcore: 策略名称
+ options.AddPolicy("allcors", corsBuilder =>
+ {
+ corsBuilder.AllowAnyHeader()
+ .AllowAnyOrigin()
+ .AllowAnyMethod();
+ });
+ });
+ }
+
+ ///
+ /// 配置跨域策略生效
+ ///
+ ///
+ public static void UseCorsExt(this WebApplication app)
+ {
+ app.UseCors("allcors");
+ }
+
+
+ }
+}
diff --git a/UIStandardWebApi.WebCore/StaticFiles/ReadStaticFilesExtensions.cs b/UIStandardWebApi.WebCore/StaticFiles/ReadStaticFilesExtensions.cs
new file mode 100644
index 0000000..ec408d0
--- /dev/null
+++ b/UIStandardWebApi.WebCore/StaticFiles/ReadStaticFilesExtensions.cs
@@ -0,0 +1,48 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.FileProviders;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace UIStandardWebApi.WebCore.StaticFiles
+{
+ ///
+ /// 读取图片信息
+ ///
+ public static class ReadStaticFilesExtensions
+ {
+ ///
+ /// 读取图片信息
+ ///
+ ///
+ ///
+ public static void ReadStaticFilesExt(this IApplicationBuilder app, string fileAddress)
+ {
+ if (string.IsNullOrWhiteSpace(fileAddress))
+ {
+ throw new Exception("配置保存图片的地址不存在");
+ }
+ if (!Directory.Exists(fileAddress))
+ {
+ Directory.CreateDirectory(fileAddress);
+ }
+ var fileProvider = new PhysicalFileProvider(fileAddress);
+ var requestPath = $"/static";
+
+ app.UseStaticFiles(new StaticFileOptions()
+ {
+ FileProvider = fileProvider,
+ RequestPath = requestPath
+ });
+
+ //展示文件列表
+ app.UseDirectoryBrowser(new DirectoryBrowserOptions
+ {
+ FileProvider = fileProvider,
+ RequestPath = requestPath
+ });
+ }
+ }
+}
diff --git a/UIStandardWebApi.WebCore/SwaggerExtend/ApiVersions.cs b/UIStandardWebApi.WebCore/SwaggerExtend/ApiVersions.cs
new file mode 100644
index 0000000..e68f634
--- /dev/null
+++ b/UIStandardWebApi.WebCore/SwaggerExtend/ApiVersions.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace UIStandardWebApi.WebCore.SwaggerExtend
+{
+ ///
+ /// Api版本枚举
+ ///
+ public enum ApiVersions
+ {
+ V1,
+ V2,
+ V3,
+ V4
+ }
+}
diff --git a/UIStandardWebApi.WebCore/SwaggerExtend/SwaggerExtensions.cs b/UIStandardWebApi.WebCore/SwaggerExtend/SwaggerExtensions.cs
new file mode 100644
index 0000000..14dac12
--- /dev/null
+++ b/UIStandardWebApi.WebCore/SwaggerExtend/SwaggerExtensions.cs
@@ -0,0 +1,92 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.OpenApi.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace UIStandardWebApi.WebCore.SwaggerExtend
+{
+ public static class SwaggerExtensions
+ {
+ ///
+ /// 配置Swagger的配置
+ ///
+ ///
+ ///
+ ///
+ public static void AddSwaggerExt(this IServiceCollection service, string docName, string docDescription)
+ {
+ service.AddEndpointsApiExplorer();
+ service.AddSwaggerGen(option =>
+ {
+ foreach (var version in typeof(ApiVersions).GetEnumNames())
+ {
+ option.SwaggerDoc(version, new OpenApiInfo()
+ {
+ Title = !string.IsNullOrWhiteSpace(docName) ? docName : $"Api文档",
+ Version = version,
+ Description = !string.IsNullOrWhiteSpace(docDescription) ? docDescription : $"Api版本v1"
+ });
+ }
+ //option.OperationFilter();
+
+ // xml文档绝对路径
+ var file = Path.Combine(AppContext.BaseDirectory, $"{AppDomain.CurrentDomain.FriendlyName}.xml");
+ // true : 显示控制器层注释
+ option.IncludeXmlComments(file, true);
+ // 对action的名称进行排序,如果有多个,就可以看见效果了。
+ option.OrderActionsBy(o => o.RelativePath);
+
+ //#region 支持jwt token授权
+ //{
+ // //添加安全定义--配置支持token授权机制
+ // option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
+ // {
+ // Description = "请输入token,格式为 Bearer xxxxxxxx(注意中间必须有空格)",
+ // Name = "Authorization",
+ // In = ParameterLocation.Header,
+ // Type = SecuritySchemeType.ApiKey,
+ // BearerFormat = "JWT",
+ // Scheme = "Bearer"
+ // });
+ // //添加安全要求
+ // option.AddSecurityRequirement(new OpenApiSecurityRequirement
+ // {
+ // {
+ // new OpenApiSecurityScheme
+ // {
+ // Reference =new OpenApiReference()
+ // {
+ // Type = ReferenceType.SecurityScheme,
+ // Id ="Bearer"
+ // }
+ // },
+ // new string[]{ }
+ // }
+ // });
+ //}
+ //#endregion
+ });
+ }
+
+
+ ///
+ /// 使用Swagger中间件
+ ///
+ ///
+ public static void UseSwaggerExt(this WebApplication app, string docName)
+ {
+ app.UseSwagger();
+ app.UseSwaggerUI(option =>
+ {
+ foreach (string version in typeof(ApiVersions).GetEnumNames())
+ {
+ option.SwaggerEndpoint($"/swagger/{version}/swagger.json", string.IsNullOrWhiteSpace(docName) ? docName : $"软件标准化Api文档【{version}】版本");
+ }
+ });
+ }
+ }
+}
diff --git a/UIStandardWebApi.WebCore/SwaggerExtend/SwaggerFileUploadFilter.cs b/UIStandardWebApi.WebCore/SwaggerExtend/SwaggerFileUploadFilter.cs
new file mode 100644
index 0000000..d3772ce
--- /dev/null
+++ b/UIStandardWebApi.WebCore/SwaggerExtend/SwaggerFileUploadFilter.cs
@@ -0,0 +1,56 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.OpenApi.Models;
+using Swashbuckle.AspNetCore.SwaggerGen;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace UIStandardWebApi.WebCore.SwaggerExtend
+{
+ public class SwaggerFileUploadFilter : IOperationFilter
+ {
+ public void Apply(OpenApiOperation operation, OperationFilterContext context)
+ {
+ const string FileUploadContentType = "multipart/form-data";
+ if (operation.RequestBody == null ||
+ !operation.RequestBody.Content.Any(x =>
+ x.Key.Equals(FileUploadContentType, StringComparison.InvariantCultureIgnoreCase)))
+ {
+ return;
+ }
+
+ if (context.ApiDescription.ParameterDescriptions[0].Type == typeof(HttpRequest))
+ {
+ operation.RequestBody = new OpenApiRequestBody
+ {
+ Description = "文件上传",
+ Content = new Dictionary
+ {
+ {
+ FileUploadContentType, new OpenApiMediaType
+ {
+ Schema = new OpenApiSchema
+ {
+ Type = "object",
+ Required = new HashSet{ "file" },
+ Properties = new Dictionary
+ {
+ {
+ "file", new OpenApiSchema()
+ {
+ Type = "string",
+ Format = "binary"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ };
+ }
+ }
+ }
+}
diff --git a/UIStandardWebApi.WebCore/UIStandardWebApi.WebCore.csproj b/UIStandardWebApi.WebCore/UIStandardWebApi.WebCore.csproj
new file mode 100644
index 0000000..92b8f09
--- /dev/null
+++ b/UIStandardWebApi.WebCore/UIStandardWebApi.WebCore.csproj
@@ -0,0 +1,16 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
diff --git a/UIStandardWebApi.sln b/UIStandardWebApi.sln
new file mode 100644
index 0000000..5eb7733
--- /dev/null
+++ b/UIStandardWebApi.sln
@@ -0,0 +1,43 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.13.35919.96
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UIStandardWebApi", "UIStandardWebApi\UIStandardWebApi.csproj", "{1A831663-E659-4584-B908-5D0C358E8887}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UIStandardWebApi.WebCore", "UIStandardWebApi.WebCore\UIStandardWebApi.WebCore.csproj", "{F926756D-DACD-43EA-8C56-E220E3C02820}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UIStandardWebApi.Entity", "UIStandardWebApi.Entity\UIStandardWebApi.Entity.csproj", "{E5D266AE-65A8-401C-8F6F-6ADB10BEB1C6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UIStandardWebApi.EntityDto", "UIStandardWebApi.EntityDto\UIStandardWebApi.EntityDto.csproj", "{F8D34A35-F030-48FF-927A-F370F803D46A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1A831663-E659-4584-B908-5D0C358E8887}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1A831663-E659-4584-B908-5D0C358E8887}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1A831663-E659-4584-B908-5D0C358E8887}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1A831663-E659-4584-B908-5D0C358E8887}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F926756D-DACD-43EA-8C56-E220E3C02820}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F926756D-DACD-43EA-8C56-E220E3C02820}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F926756D-DACD-43EA-8C56-E220E3C02820}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F926756D-DACD-43EA-8C56-E220E3C02820}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E5D266AE-65A8-401C-8F6F-6ADB10BEB1C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E5D266AE-65A8-401C-8F6F-6ADB10BEB1C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E5D266AE-65A8-401C-8F6F-6ADB10BEB1C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E5D266AE-65A8-401C-8F6F-6ADB10BEB1C6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F8D34A35-F030-48FF-927A-F370F803D46A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F8D34A35-F030-48FF-927A-F370F803D46A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F8D34A35-F030-48FF-927A-F370F803D46A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F8D34A35-F030-48FF-927A-F370F803D46A}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {AE68BCD9-7F48-4EF2-8FB7-A612E7A4C9B9}
+ EndGlobalSection
+EndGlobal
diff --git a/UIStandardWebApi/App.config b/UIStandardWebApi/App.config
new file mode 100644
index 0000000..d796617
--- /dev/null
+++ b/UIStandardWebApi/App.config
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/UIStandardWebApi/Common/ApiResult.cs b/UIStandardWebApi/Common/ApiResult.cs
new file mode 100644
index 0000000..7be6173
--- /dev/null
+++ b/UIStandardWebApi/Common/ApiResult.cs
@@ -0,0 +1,36 @@
+namespace UIStandardWebApi.Common
+{
+ ///
+ /// api
+ ///
+ public class ApiResult
+ {
+ ///
+ /// 是否正常返回
+ ///
+ public bool Success { get; set; }
+
+ ///
+ /// 处理消息
+ ///
+ public string? Message { get; set; }
+ }
+
+
+ ///
+ /// api 数据结果
+ ///
+ ///
+ public class ApiDataResult : ApiResult
+ {
+ ///
+ /// 结果集
+ ///
+ public T? Data { get; set; }
+
+ ///
+ /// 冗余结果
+ ///
+ public object? OValue { get; set; }
+ }
+}
diff --git a/UIStandardWebApi/Common/AppSettingsJson.cs b/UIStandardWebApi/Common/AppSettingsJson.cs
new file mode 100644
index 0000000..aa1471b
--- /dev/null
+++ b/UIStandardWebApi/Common/AppSettingsJson.cs
@@ -0,0 +1,24 @@
+namespace UIStandardWebApi.Common
+{
+ ///
+ /// 读取AppSettings.Json文件内容
+ ///
+ public static class AppSettingsJson
+ {
+ public static string ApplicationExeDirectory()
+ {
+ var location = System.Reflection.Assembly.GetExecutingAssembly().Location;
+ var appRoot = Path.GetDirectoryName(location);
+ return appRoot;
+ }
+ public static IConfigurationRoot GetAppSettings()
+ {
+ string applicationExeDirectory = ApplicationExeDirectory();
+ var builder = new ConfigurationBuilder()
+ .SetBasePath(applicationExeDirectory)
+ .AddJsonFile("appsettings.json");
+ return builder.Build();
+ }
+
+ }
+}
diff --git a/UIStandardWebApi/Common/Appsettings.cs b/UIStandardWebApi/Common/Appsettings.cs
new file mode 100644
index 0000000..f16b0c8
--- /dev/null
+++ b/UIStandardWebApi/Common/Appsettings.cs
@@ -0,0 +1,67 @@
+using Microsoft.Extensions.Configuration.Json;
+
+namespace UIStandardWebApi.Common
+{
+ ///
+ /// appsettings.json操作类
+ ///
+ public class Appsettings
+ {
+ static IConfiguration Configuration { get; set; }
+ static string contentPath { get; set; }
+
+ public Appsettings(string contentPath)
+ {
+ string Path = "appsettings.json";
+
+ //如果你把配置文件 是 根据环境变量来分开了,可以这样写
+ //Path = $"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json";
+
+ Configuration = new ConfigurationBuilder()
+ .SetBasePath(contentPath)
+ .Add(new JsonConfigurationSource { Path = Path, Optional = false, ReloadOnChange = true })//这样的话,可以直接读目录里的json文件,而不是 bin 文件夹下的,所以不用修改复制属性
+ .Build();
+ }
+
+ public Appsettings(IConfiguration configuration)
+ {
+ Configuration = configuration;
+ }
+
+ ///
+ /// 封装要操作的字符
+ ///
+ /// 节点配置
+ ///
+ public static string app(params string[] sections)
+ {
+ try
+ {
+
+ if (sections.Any())
+ {
+ return Configuration[string.Join(":", sections)];
+ }
+ }
+ catch (Exception)
+ {
+
+ }
+
+ return "";
+ }
+
+ ///
+ /// 递归获取配置信息数组
+ ///
+ ///
+ ///
+ ///
+ public static List app(params string[] sections)
+ {
+ List list = new List();
+ Configuration.Bind(string.Join(":", sections), list);
+ return list;
+ }
+ }
+}
diff --git a/UIStandardWebApi/Common/DataParsing.cs b/UIStandardWebApi/Common/DataParsing.cs
new file mode 100644
index 0000000..e9a3405
--- /dev/null
+++ b/UIStandardWebApi/Common/DataParsing.cs
@@ -0,0 +1,18 @@
+namespace UIStandardWebApi.Common
+{
+
+ ///
+ /// 数据解析
+ ///
+ public class DataParsing
+ {
+ ///
+ /// 数据解析
+ ///
+ ///
+ public void ParsingData(List byteList)
+ {
+
+ }
+ }
+}
diff --git a/UIStandardWebApi/Common/JwtService/JWTSwaggerGen.cs b/UIStandardWebApi/Common/JwtService/JWTSwaggerGen.cs
new file mode 100644
index 0000000..f31b5fc
--- /dev/null
+++ b/UIStandardWebApi/Common/JwtService/JWTSwaggerGen.cs
@@ -0,0 +1,42 @@
+using Microsoft.OpenApi.Models;
+
+namespace UIStandardWebApi.Common.JwtService
+{
+ ///
+ /// JWT鉴权授权扩展
+ ///
+ public static class JWTSwaggerGen
+ {
+ ///
+ /// 解决Swagger右上角的Authorize权限按钮不显示
+ ///
+ ///
+ public static void AddJWTSwaggerGen(this WebApplicationBuilder builder)
+ {
+ builder.Services.AddSwaggerGen(c =>
+ {
+ var security = new OpenApiSecurityRequirement()
+ {
+ { new OpenApiSecurityScheme
+ {
+ Reference = new OpenApiReference()
+ {
+ Id = "Bearer",
+ Type = ReferenceType.SecurityScheme
+ }
+ }, Array.Empty() }
+ };
+ c.AddSecurityRequirement(security);//添加一个必须的全局安全信息,和AddSecurityDefinition方法指定的方案名称要一致,这里是Bearer。
+ c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
+ {
+ Description = "JWT授权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\"",
+ Name = "Authorization",//jwt默认的参数名称
+ In = ParameterLocation.Header,//jwt默认存放Authorization信息的位置(请求头中)
+ Type = SecuritySchemeType.ApiKey,
+ BearerFormat = "JWT",
+ Scheme = "Bearer"
+ });
+ });
+ }
+ }
+}
diff --git a/UIStandardWebApi/Common/JwtService/JWTTokenOptions.cs b/UIStandardWebApi/Common/JwtService/JWTTokenOptions.cs
new file mode 100644
index 0000000..313b7e1
--- /dev/null
+++ b/UIStandardWebApi/Common/JwtService/JWTTokenOptions.cs
@@ -0,0 +1,11 @@
+namespace UIStandardWebApi.Common.JwtService
+{
+ public class JWTTokenOptions
+ {
+ public string? Audience { get; set; }
+
+ public string? SecurityKey { get; set; }
+
+ public string? Issuer { get; set; }
+ }
+}
diff --git a/UIStandardWebApi/Common/JwtService/RSAHelper.cs b/UIStandardWebApi/Common/JwtService/RSAHelper.cs
new file mode 100644
index 0000000..98334b7
--- /dev/null
+++ b/UIStandardWebApi/Common/JwtService/RSAHelper.cs
@@ -0,0 +1,58 @@
+using Newtonsoft.Json;
+using System.Security.Cryptography;
+
+namespace UIStandardWebApi.Common.JwtService
+{
+ public class RSAHelper
+ {
+ ///
+ /// 从本地文件中读取用来签发 Token 的 RSA Key
+ ///
+ /// 存放密钥的文件夹路径
+ ///
+ ///
+ ///
+ public static bool TryGetKeyParameters(string filePath, bool withPrivate, out RSAParameters keyParameters)
+ {
+ string filename = withPrivate ? "key.json" : "key.public.json";
+ string fileTotalPath = Path.Combine(filePath, filename);
+ keyParameters = default;
+ if (!File.Exists(fileTotalPath))
+ {
+ return false;
+ }
+ else
+ {
+ keyParameters = JsonConvert.DeserializeObject(File.ReadAllText(fileTotalPath));
+ return true;
+ }
+ }
+
+
+ ///
+ /// 生成并保存 RSA 公钥与私钥
+ ///
+ /// 存放密钥的文件夹路径
+ ///
+ public static RSAParameters GenerateAndSaveKey(string filePath, bool withPrivate = true)
+ {
+ RSAParameters publicKeys, privateKeys;
+ using (var rsa = new RSACryptoServiceProvider(2048))//即时生成
+ {
+ try
+ {
+ privateKeys = rsa.ExportParameters(true);
+ publicKeys = rsa.ExportParameters(false);
+ }
+ finally
+ {
+ rsa.PersistKeyInCsp = false;
+ }
+ }
+ File.WriteAllText(Path.Combine(filePath, "key.json"), JsonConvert.SerializeObject(privateKeys));
+
+ File.WriteAllText(Path.Combine(filePath, "key.public.json"), JsonConvert.SerializeObject(publicKeys));
+ return withPrivate ? privateKeys : publicKeys;
+ }
+ }
+}
diff --git a/UIStandardWebApi/Common/MD5Encrypt.cs b/UIStandardWebApi/Common/MD5Encrypt.cs
new file mode 100644
index 0000000..2248e4d
--- /dev/null
+++ b/UIStandardWebApi/Common/MD5Encrypt.cs
@@ -0,0 +1,85 @@
+using System.Security.Cryptography;
+using System.Text;
+
+namespace UIStandardWebApi.Common
+{
+ ///
+ /// MD5加密
+ ///
+ public class MD5Encrypt
+ {
+ #region MD5
+ ///
+ /// MD5加密,和动网上的16/32位MD5加密结果相同,
+ /// 使用的UTF8编码
+ ///
+ /// 待加密字串
+ /// 16或32值之一,其它则采用.net默认MD5加密算法
+ /// 加密后的字串
+ public static string Encrypt(string source, int length = 32)//默认参数
+ {
+ if (string.IsNullOrEmpty(source)) return string.Empty;
+ HashAlgorithm provider = CryptoConfig.CreateFromName("MD5") as HashAlgorithm;
+ byte[] bytes = Encoding.UTF8.GetBytes(source);//这里需要区别编码的
+ byte[] hashValue = provider.ComputeHash(bytes);
+ StringBuilder sb = new StringBuilder();
+ switch (length)
+ {
+ case 16://16位密文是32位密文的9到24位字符
+ for (int i = 4; i < 12; i++)
+ {
+ sb.Append(hashValue[i].ToString("x2"));
+ }
+ break;
+ case 32:
+ for (int i = 0; i < 16; i++)
+ {
+ sb.Append(hashValue[i].ToString("x2"));
+ }
+ break;
+ default:
+ for (int i = 0; i < hashValue.Length; i++)
+ {
+ sb.Append(hashValue[i].ToString("x2"));
+ }
+ break;
+ }
+ return sb.ToString();
+ }
+ #endregion MD5
+
+ #region MD5摘要
+ ///
+ /// 获取文件的MD5摘要
+ ///
+ ///
+ ///
+ public static string AbstractFile(string fileName)
+ {
+ using (FileStream file = new FileStream(fileName, FileMode.Open))
+ {
+ return AbstractFile(file);
+ }
+ }
+
+
+ ///
+ /// 根据stream获取文件摘要
+ ///
+ ///
+ ///
+ public static string AbstractFile(Stream stream)
+ {
+ MD5 md5 = new MD5CryptoServiceProvider();
+ byte[] retVal = md5.ComputeHash(stream);
+
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < retVal.Length; i++)
+ {
+ sb.Append(retVal[i].ToString("x2"));
+ }
+ return sb.ToString();
+ }
+ #endregion
+ }
+}
diff --git a/UIStandardWebApi/Common/SocketModel/Client.cs b/UIStandardWebApi/Common/SocketModel/Client.cs
new file mode 100644
index 0000000..0ee6c16
--- /dev/null
+++ b/UIStandardWebApi/Common/SocketModel/Client.cs
@@ -0,0 +1,194 @@
+using System.Net.Sockets;
+using System.Net;
+using static UIStandardWebApi.Common.SocketModel.Sockets;
+
+namespace UIStandardWebApi.Common.SocketModel
+{
+ ///
+ /// 客户端通信类
+ ///
+ public class Client : SocketObject
+ {
+ public PushSockets pushSockets;
+
+ bool IsClose = false;
+ ///
+ /// 当前管理对象
+ ///
+ Sockets sk;
+ ///
+ /// 客户端
+ ///
+ TcpClient client;
+ ///
+ /// 当前连接服务端地址
+ ///
+ IPAddress Ipaddress;
+ ///
+ /// 当前连接服务端端口号
+ ///
+ int Port;
+ ///
+ /// 服务端IP+端口
+ ///
+ IPEndPoint ip;
+ ///
+ /// 发送与接收使用的流
+ ///
+ NetworkStream nStream;
+
+ ///
+ /// 初始化Socket
+ ///
+ ///
+ ///
+ public override void InitSocket(IPAddress ipaddress, int port)
+ {
+ Ipaddress = ipaddress;
+ Port = port;
+ ip = new IPEndPoint(Ipaddress, Port);
+ client = new TcpClient();
+ }
+ ///
+ /// 初始化Socket
+ ///
+ /// ipd地址
+ /// 端口
+ public override void InitSocket(string ipaddress, int port)
+ {
+ Ipaddress = IPAddress.Parse(ipaddress);
+ Port = port;
+ ip = new IPEndPoint(Ipaddress, Port);
+ client = new TcpClient();
+ }
+ ///
+ /// 重写Start方法,其实就是连接服务端
+ ///
+ public override void Start()
+ {
+ Connect();
+ }
+ ///
+ /// 连接
+ ///
+ public bool Connect()
+ {
+ try
+ {
+ client.Connect(ip);
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+ nStream = new NetworkStream(client.Client, true);
+ sk = new Sockets(ip, client, nStream);
+ sk.nStream.BeginRead(sk.RecBuffer, 0, sk.RecBuffer.Length, new AsyncCallback(EndReader), sk);
+ return true;
+ }
+ ///
+ /// 读取
+ ///
+ private void EndReader(IAsyncResult ir)
+ {
+ Sockets s = ir.AsyncState as Sockets;
+ try
+ {
+ if (s != null)
+ {
+ if (IsClose && client == null)
+ {
+ sk.nStream.Close();
+ sk.nStream.Dispose();
+ return;
+ }
+ s.Offset = s.nStream.EndRead(ir);
+ if (pushSockets != null)
+ pushSockets.Invoke(s);//推送至UI
+ sk.nStream.BeginRead(sk.RecBuffer, 0, sk.RecBuffer.Length, new AsyncCallback(EndReader), sk);
+ }
+ }
+ catch (Exception skex)
+ {
+ Sockets sks = s;
+ sks.ex = skex;
+ sks.ClientDispose = true;
+ if (pushSockets != null)
+ pushSockets.Invoke(sks);//推送至UI
+ }
+ }
+ ///
+ /// 停止
+ ///
+ public override void Stop()
+ {
+ Sockets sks = new Sockets();
+ try
+ {
+ if (client != null)
+ {
+ client.Client.Shutdown(SocketShutdown.Both);
+ Thread.Sleep(10);
+ client.Close();
+ IsClose = true;
+ client = null;
+ }
+ else
+ {
+ sks.ex = new Exception("客户端没有初始化.!");
+ }
+ if (pushSockets != null)
+ pushSockets.Invoke(sks);//推送至UI
+ }
+ catch (Exception ex)
+ {
+ sks.ex = ex;
+ }
+ }
+ ///
+ /// 发送消息
+ ///
+ public void SendData(byte[] SendData)
+ {
+ try
+ {
+ if (client == null || !client.Connected)
+ {
+ Sockets sks = new Sockets();
+ sks.ex = new Exception("客户端无连接..");
+ sks.ClientDispose = true;
+ if (pushSockets != null)
+ pushSockets.Invoke(sks);//推送至UI
+ }
+ if (client.Connected) //如果连接则发送
+ {
+ if (nStream == null)
+ {
+ nStream = client.GetStream();
+ }
+ nStream.Write(SendData, 0, SendData.Length);
+ }
+ }
+ catch (Exception skex)
+ {
+ Sockets sks = new Sockets();
+ sks.ex = skex;
+ sks.ClientDispose = true;
+ if (pushSockets != null)
+ pushSockets.Invoke(sks);//推送至UI
+ }
+ }
+
+ public bool Is_Connected()
+ {
+ return client.Connected;
+ }
+
+ public bool IsOnline()
+ {
+ if (client == null)
+ return false;
+ return !(client.Client.Poll(1000, SelectMode.SelectRead) && client.Client.Available == 0 || !client.Client.Connected);
+ }
+ }
+}
diff --git a/UIStandardWebApi/Common/SocketModel/SocketListening.cs b/UIStandardWebApi/Common/SocketModel/SocketListening.cs
new file mode 100644
index 0000000..be8eec7
--- /dev/null
+++ b/UIStandardWebApi/Common/SocketModel/SocketListening.cs
@@ -0,0 +1,334 @@
+using System.Net.Sockets;
+using System.Net;
+using System.Runtime.InteropServices;
+using Socket = System.Net.Sockets.Socket;
+
+namespace UIStandardWebApi.Common.SocketModel
+{
+ ///
+ /// 开启服务器监听 便于Client连接
+ ///
+ public class SocketListening
+ {
+ //通信定义
+ private static Socket socket = null;
+
+ ///
+ /// 创建负责监听的线程;
+ ///
+ Thread? trdConnect;
+ ///
+ /// Socket连接状态
+ ///
+ public static bool g_Receive;
+
+ //获取当前程序运行路径
+ private string Save_Path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"通信连接记录\";
+
+ ///
+ /// 定义公共Ip
+ ///
+ public static string? g_ip;
+
+
+
+ ///
+ /// 键值对集合:键为IP地址,值为Socket
+ /// 将远程连接的客户端的IP地址和端口号存入集合中
+ ///
+ public static Dictionary g_dicSocket = new Dictionary();
+
+ //监听客户端连接的标志
+ private static bool Flag_Listen = true;
+
+ //定义为任意IP
+ IPAddress ip = IPAddress.Any;
+
+ //定义端口号 8899
+ private int port = 8899;
+
+ ///
+ /// 服务端开启即等待连接
+ ///
+ public bool OpenServer(int port)
+ {
+ try
+ {
+ Flag_Listen = true;
+
+ //在服务器端创建一个负责IP地址和端口号的Socket
+ socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+
+ tools.AddLgoToTXT("通信连接记录信息.txt", Save_Path + DateTime.Now.ToString("yyyy_MM_dd") + @"\", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " 创建端口号连接" + "\r\n");
+ //创建端口号对象
+ IPEndPoint point = new IPEndPoint(ip, port);
+
+ try
+ {
+ //监听
+ socket.Bind(point);
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+ // 设置监听队列的长度;
+ socket.Listen(10);
+ // 创建负责监听的线程;
+ trdConnect = new Thread(ListenConnect);
+ trdConnect.IsBackground = true;
+ trdConnect.Start();
+
+ return true;
+ }
+ catch (Exception ex)
+ {
+ tools.AddLgoToTXT("通信连接异常记录信息.txt", Save_Path + DateTime.Now.ToString("yyyy_MM_dd") + @"\", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + ex.Message + "\r\n");
+ return false;
+ }
+ }
+
+ ///
+ /// 监听连接
+ ///
+ ///
+ private void ListenConnect()
+ {
+ while (Flag_Listen)
+ {
+ try
+ {
+ //负责和客户端通信的Socket
+ SocketStatic.g_socketSend = socket.Accept();
+
+ SocketStatic.g_socketSend.IOControl(IOControlCode.KeepAliveValues, GetKeepAliveData(), null);
+ SocketStatic.g_socketSend.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
+
+ g_ip = SocketStatic.g_socketSend.RemoteEndPoint.ToString();
+
+ if (!g_dicSocket.ContainsKey(g_ip))
+ {
+ //将远程连接的客户端的IP地址和端口号存入集合中
+ g_dicSocket.Add(g_ip, SocketStatic.g_socketSend);
+ g_Receive = true;
+
+ tools.AddLgoToTXT("通信连接记录信息.txt", Save_Path + DateTime.Now.ToString("yyyy_MM_dd") + @"\", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " 新增的远程连接:" + g_ip + "\r\n");
+
+
+ List