添加项目文件。

This commit is contained in:
MoYue 2025-04-08 08:41:01 +08:00
parent 95f57365e8
commit e1f0bd4c7d
37 changed files with 2571 additions and 0 deletions

View File

@ -0,0 +1,7 @@
namespace UIStandardWebApi.Entity
{
public class Class1
{
}
}

View File

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,7 @@
namespace UIStandardWebApi.EntityDto
{
public class Class1
{
}
}

View File

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@ -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
{
/// <summary>
/// Dto映射配置
/// </summary>
public class AutoMapperConfigs : Profile
{
/// <summary>
/// 配置映射
/// </summary>
public AutoMapperConfigs()
{
}
}
}

View File

@ -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
{
/// <summary>
/// 跨域
/// </summary>
public static class CorsExtension
{
/// <summary>
/// 配置跨域策略
/// </summary>
/// <param name="services"></param>
public static void AddCorsExt(this IServiceCollection services)
{
services.AddCors(options =>
{
// allcore: 策略名称
options.AddPolicy("allcors", corsBuilder =>
{
corsBuilder.AllowAnyHeader()
.AllowAnyOrigin()
.AllowAnyMethod();
});
});
}
/// <summary>
/// 配置跨域策略生效
/// </summary>
/// <param name="app"></param>
public static void UseCorsExt(this WebApplication app)
{
app.UseCors("allcors");
}
}
}

View File

@ -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
{
/// <summary>
/// 读取图片信息
/// </summary>
public static class ReadStaticFilesExtensions
{
/// <summary>
/// 读取图片信息
/// </summary>
/// <param name="app"></param>
/// <param name="directoryPath"></param>
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
});
}
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UIStandardWebApi.WebCore.SwaggerExtend
{
/// <summary>
/// Api版本枚举
/// </summary>
public enum ApiVersions
{
V1,
V2,
V3,
V4
}
}

View File

@ -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
{
/// <summary>
/// 配置Swagger的配置
/// </summary>
/// <param name="service"></param>
/// <param name="docName"></param>
/// <param name="docDescription"></param>
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<SwaggerFileUploadFcilter>();
// 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
});
}
/// <summary>
/// 使用Swagger中间件
/// </summary>
/// <param name="app"></param>
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}】版本");
}
});
}
}
}

View File

@ -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<string, OpenApiMediaType>
{
{
FileUploadContentType, new OpenApiMediaType
{
Schema = new OpenApiSchema
{
Type = "object",
Required = new HashSet<string>{ "file" },
Properties = new Dictionary<string, OpenApiSchema>
{
{
"file", new OpenApiSchema()
{
Type = "string",
Format = "binary"
}
}
}
}
}
}
}
};
}
}
}
}

View File

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="CSRedisCore" Version="3.8.804" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
</ItemGroup>
</Project>

43
UIStandardWebApi.sln Normal file
View File

@ -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

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<!--数据库连接信息-->
<connectionStrings>
<!--<add name="db" connectionString="Data Source=10.20.98.142;Initial Catalog=InSituLaboratoryWeb;User ID=sa;Password=zttZTT123!;MultipleActiveResultSets=true" />-->
<add name="db" connectionString="Data Source= NB10920;Initial Catalog=InSituLaboratoryWeb;User ID=sa;Password=zttZTT123;MultipleActiveResultSets=true" />
</connectionStrings>
</configuration>

View File

@ -0,0 +1,36 @@
namespace UIStandardWebApi.Common
{
/// <summary>
/// api
/// </summary>
public class ApiResult
{
/// <summary>
/// 是否正常返回
/// </summary>
public bool Success { get; set; }
/// <summary>
/// 处理消息
/// </summary>
public string? Message { get; set; }
}
/// <summary>
/// api 数据结果
/// </summary>
/// <typeparam name="T"></typeparam>
public class ApiDataResult<T> : ApiResult
{
/// <summary>
/// 结果集
/// </summary>
public T? Data { get; set; }
/// <summary>
/// 冗余结果
/// </summary>
public object? OValue { get; set; }
}
}

View File

@ -0,0 +1,24 @@
namespace UIStandardWebApi.Common
{
/// <summary>
/// 读取AppSettings.Json文件内容
/// </summary>
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();
}
}
}

View File

@ -0,0 +1,67 @@
using Microsoft.Extensions.Configuration.Json;
namespace UIStandardWebApi.Common
{
/// <summary>
/// appsettings.json操作类
/// </summary>
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;
}
/// <summary>
/// 封装要操作的字符
/// </summary>
/// <param name="sections">节点配置</param>
/// <returns></returns>
public static string app(params string[] sections)
{
try
{
if (sections.Any())
{
return Configuration[string.Join(":", sections)];
}
}
catch (Exception)
{
}
return "";
}
/// <summary>
/// 递归获取配置信息数组
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sections"></param>
/// <returns></returns>
public static List<T> app<T>(params string[] sections)
{
List<T> list = new List<T>();
Configuration.Bind(string.Join(":", sections), list);
return list;
}
}
}

View File

@ -0,0 +1,18 @@
namespace UIStandardWebApi.Common
{
/// <summary>
/// 数据解析
/// </summary>
public class DataParsing
{
/// <summary>
/// 数据解析
/// </summary>
/// <param name="byteList"></param>
public void ParsingData(List<byte> byteList)
{
}
}
}

View File

@ -0,0 +1,42 @@
using Microsoft.OpenApi.Models;
namespace UIStandardWebApi.Common.JwtService
{
/// <summary>
/// JWT鉴权授权扩展
/// </summary>
public static class JWTSwaggerGen
{
/// <summary>
/// 解决Swagger右上角的Authorize权限按钮不显示
/// </summary>
/// <param name="builder"></param>
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<string>() }
};
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"
});
});
}
}
}

View File

@ -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; }
}
}

View File

@ -0,0 +1,58 @@
using Newtonsoft.Json;
using System.Security.Cryptography;
namespace UIStandardWebApi.Common.JwtService
{
public class RSAHelper
{
/// <summary>
/// 从本地文件中读取用来签发 Token 的 RSA Key
/// </summary>
/// <param name="filePath">存放密钥的文件夹路径</param>
/// <param name="withPrivate"></param>
/// <param name="keyParameters"></param>
/// <returns></returns>
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<RSAParameters>(File.ReadAllText(fileTotalPath));
return true;
}
}
/// <summary>
/// 生成并保存 RSA 公钥与私钥
/// </summary>
/// <param name="filePath">存放密钥的文件夹路径</param>
/// <returns></returns>
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;
}
}
}

View File

@ -0,0 +1,85 @@
using System.Security.Cryptography;
using System.Text;
namespace UIStandardWebApi.Common
{
/// <summary>
/// MD5加密
/// </summary>
public class MD5Encrypt
{
#region MD5
/// <summary>
/// MD5加密,和动网上的16/32位MD5加密结果相同,
/// 使用的UTF8编码
/// </summary>
/// <param name="source">待加密字串</param>
/// <param name="length">16或32值之一,其它则采用.net默认MD5加密算法</param>
/// <returns>加密后的字串</returns>
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摘要
/// <summary>
/// 获取文件的MD5摘要
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string AbstractFile(string fileName)
{
using (FileStream file = new FileStream(fileName, FileMode.Open))
{
return AbstractFile(file);
}
}
/// <summary>
/// 根据stream获取文件摘要
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
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
}
}

View File

@ -0,0 +1,194 @@
using System.Net.Sockets;
using System.Net;
using static UIStandardWebApi.Common.SocketModel.Sockets;
namespace UIStandardWebApi.Common.SocketModel
{
/// <summary>
/// 客户端通信类
/// </summary>
public class Client : SocketObject
{
public PushSockets pushSockets;
bool IsClose = false;
/// <summary>
/// 当前管理对象
/// </summary>
Sockets sk;
/// <summary>
/// 客户端
/// </summary>
TcpClient client;
/// <summary>
/// 当前连接服务端地址
/// </summary>
IPAddress Ipaddress;
/// <summary>
/// 当前连接服务端端口号
/// </summary>
int Port;
/// <summary>
/// 服务端IP+端口
/// </summary>
IPEndPoint ip;
/// <summary>
/// 发送与接收使用的流
/// </summary>
NetworkStream nStream;
/// <summary>
/// 初始化Socket
/// </summary>
/// <param name="ipaddress"></param>
/// <param name="port"></param>
public override void InitSocket(IPAddress ipaddress, int port)
{
Ipaddress = ipaddress;
Port = port;
ip = new IPEndPoint(Ipaddress, Port);
client = new TcpClient();
}
/// <summary>
/// 初始化Socket
/// </summary>
/// <param name="ipaddress">ipd地址</param>
/// <param name="port">端口</param>
public override void InitSocket(string ipaddress, int port)
{
Ipaddress = IPAddress.Parse(ipaddress);
Port = port;
ip = new IPEndPoint(Ipaddress, Port);
client = new TcpClient();
}
/// <summary>
/// 重写Start方法,其实就是连接服务端
/// </summary>
public override void Start()
{
Connect();
}
/// <summary>
/// 连接
/// </summary>
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;
}
/// <summary>
/// 读取
/// </summary>
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
}
}
/// <summary>
/// 停止
/// </summary>
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;
}
}
/// <summary>
/// 发送消息
/// </summary>
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);
}
}
}

View File

@ -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
{
/// <summary>
/// 开启服务器监听 便于Client连接
/// </summary>
public class SocketListening
{
//通信定义
private static Socket socket = null;
/// <summary>
/// 创建负责监听的线程;
/// </summary>
Thread? trdConnect;
/// <summary>
/// Socket连接状态
/// </summary>
public static bool g_Receive;
//获取当前程序运行路径
private string Save_Path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"通信连接记录\";
/// <summary>
/// 定义公共Ip
/// </summary>
public static string? g_ip;
/// <summary>
/// 键值对集合键为IP地址值为Socket
/// 将远程连接的客户端的IP地址和端口号存入集合中
/// </summary>
public static Dictionary<string, Socket> g_dicSocket = new Dictionary<string, Socket>();
//监听客户端连接的标志
private static bool Flag_Listen = true;
//定义为任意IP
IPAddress ip = IPAddress.Any;
//定义端口号 8899
private int port = 8899;
/// <summary>
/// 服务端开启即等待连接
/// </summary>
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;
}
}
/// <summary>
/// 监听连接
/// </summary>
/// <param name="o"></param>
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<object> list = new List<object>
{
g_ip,
SocketStatic.g_socketSend
};
SocketStatic.IsConnection = true;
//开启一个新线程不停接收客户端的数据
Thread trdReceive = new Thread(DataReceive);
trdReceive.IsBackground = true;
trdReceive.Start(list);
}
}
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");
}
}
}
private byte[] GetKeepAliveData()
{
uint dummy = 0;
byte[] inOptionValues = new byte[Marshal.SizeOf(dummy) * 3];
BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0);
BitConverter.GetBytes((uint)3000).CopyTo(inOptionValues, Marshal.SizeOf(dummy));//keep-alive间隔
BitConverter.GetBytes((uint)500).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2);// 尝试间隔
return inOptionValues;
}
/// <summary>
/// 数据接收
/// </summary>
/// <param name="sokConnectionparn"></param>
private void DataReceive(object sokConnectionparn)
{
List<object> list = sokConnectionparn as List<object>;
MySession tcpClient = sokConnectionparn as MySession;
string g_ipNew = (string)list[0];
Socket socketSend = (Socket)list[1];
bool flag = true;
while (flag)
{
try
{
//客户端连接成功后,服务器接收客户端发来的消息
byte[] arrMsgRec = new byte[1024 * 1024 * 2];
// 将接受到的数据存入到输入 arrMsgRec中
int length = -1;
//判断ip是否被移除
if (!g_dicSocket.ContainsKey(g_ipNew))
{
g_Receive = false;
flag = false;
continue;
}
//判断是否连接
if (socketSend.Poll(1000, SelectMode.SelectRead) && socketSend.Available == 0)
{
//连接断开
socketSend.Close();
if (g_dicSocket.ContainsKey(g_ipNew))
{
g_dicSocket.Remove(g_ipNew);
}
tools.AddLgoToTXT("通信连接记录信息.txt", Save_Path + DateTime.Now.ToString("yyyy_MM_dd") + @"\", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " ReceiveError移除远程连接" + g_ipNew + "\r\n");
if (g_ipNew == g_ip)
{
g_Receive = false;
SocketStatic.g_socketSend = null;
}
else
{
g_Receive = true;
}
flag = false;
SocketStatic.IsConnection = false;
continue;
}
else
{
try
{
//实际接收到的有效字节数,,并返回数据的长度
length = socketSend.Receive(arrMsgRec);
}
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");
flag = false;
tcpClient = null;
socketSend = null;
CloseServer();//关闭服务器
OpenServer(8899);
break;
}
}
byte[] buf = new byte[length];
Array.Copy(arrMsgRec, buf, length);
SocketStatic.dataParsing.ParsingData(new List<byte>(buf));
}
catch (Exception)
{
throw;
}
}
}
public class MySession
{
public Socket TcpSocket;//socket对象
public List<byte> m_Buffer = new List<byte>();//数据缓存区
public MySession()
{
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="buf"></param>
public void Send(byte[] buf)
{
if (buf != null)
{
try
{
TcpSocket.Send(buf);
}
catch (Exception err)
{
Console.WriteLine("发送指令失败,当前设备未连接");
}
}
}
/// <summary>
/// 获取连接的ip
/// </summary>
/// <returns></returns>
public string GetIp()
{
IPEndPoint clientipe = (IPEndPoint)TcpSocket.RemoteEndPoint;
string _ip = clientipe.Address.ToString();
return _ip;
}
/// <summary>
/// 关闭连接
/// </summary>
public void Close()
{
TcpSocket.Shutdown(SocketShutdown.Both);
}
/// <summary>
/// 提取正确数据包
/// </summary>
public byte[] GetBuffer(int startIndex, int size)
{
byte[] buf = new byte[size];
m_Buffer.CopyTo(startIndex, buf, 0, size);
m_Buffer.RemoveRange(0, startIndex + size);
return buf;
}
/// <summary>
/// 添加队列数据
/// </summary>
/// <param name="buffer"></param>
public void AddQueue(byte[] buffer)
{
m_Buffer.AddRange(buffer);
}
/// <summary>
/// 清除缓存
/// </summary>
public void ClearQueue()
{
m_Buffer.Clear();
}
}
/// <summary>
/// 关闭服务
/// </summary>
public static void CloseServer()
{
lock (g_dicSocket)
{
foreach (var item in g_dicSocket)
{
item.Value.Close();//关闭每一个连接
}
g_dicSocket.Clear();
}
SocketStatic.IsConnection = false;
Flag_Listen = true;
if (socket != null)
socket.Close();
}
}
}

View File

@ -0,0 +1,25 @@
using System.Net.Sockets;
namespace UIStandardWebApi.Common.SocketModel
{
/// <summary>
/// 定义一个Socket静态类用于连接断开 ,接收,发送
/// </summary>
public static class SocketStatic
{
/// <summary>
/// 定义数据解析类
/// </summary>
public static DataParsing dataParsing = new DataParsing();
/// <summary>
/// 负责和客户端通信的Socket
/// </summary>
public static Socket? g_socketSend;
/// <summary>
/// 服务端判断是否有客户端连接
/// </summary>
public static bool IsConnection;
}
}

View File

@ -0,0 +1,107 @@
using System.Net.Sockets;
using System.Net;
namespace UIStandardWebApi.Common.SocketModel
{
/// <summary>
/// Sockets 通信类
/// </summary>
public class Sockets
{
public delegate void PushSockets(Sockets sockets);
/// <summary>
///
/// </summary>
public Sockets()
{
}
/// <summary>
/// 创建Sockets对象
/// </summary>
/// <param name="ip">Ip地址</param>
/// <param name="client">TcpClient</param>
/// <param name="ns">承载客户端Socket的网络流</param>
public Sockets(IPEndPoint ip, TcpClient client, NetworkStream ns)
{
Ip = ip;
Client = client;
nStream = ns;
}
/// <summary>
/// 创建Sockets对象
/// </summary>
/// <param name="name">用户名</param>
/// <param name="pass">密码</param>
/// <param name="ip">Ip地址</param>
/// <param name="client">TcpClient</param>
/// <param name="ns">承载客户端Socket的网络流</param>
public Sockets(string name, string pass, IPEndPoint ip, TcpClient client, NetworkStream ns)
{
UserName = name;
Password = pass;
Ip = ip;
Client = client;
nStream = ns;
}
/// <summary>
/// 接收缓冲区
/// </summary>
public byte[] RecBuffer = new byte[8 * 1024];
/// <summary>
/// 发送缓冲区
/// </summary>
public byte[] SendBuffer = new byte[8 * 1024];
/// <summary>
/// 异步接收后包的大小
/// </summary>
public int Offset { get; set; }
/// <summary>
/// 用户名
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 密码
/// </summary>
public string Password { get; set; }
/// <summary>
/// 当前IP地址端口号
/// </summary>
public IPEndPoint Ip { get; set; }
/// <summary>
/// 客户端主通信程序
/// </summary>
public TcpClient Client { get; set; }
/// <summary>
/// 承载客户端Socket的网络流
/// </summary>
public NetworkStream nStream { get; set; }
/// <summary>
/// 发生异常时不为null
/// </summary>
public Exception ex { get; set; }
/// <summary>
/// 新客户端标识.如果推送器发现此标识为true,那么认为是客户端上线 仅服务端有效
/// </summary>
public bool NewClientFlag { get; set; }
/// <summary>
/// 客户端退出标识.如果服务端发现此标识为true,那么认为客户端下线
/// 客户端接收此标识时,认为客户端异常.
/// </summary>
public bool ClientDispose { get; set; }
}
/// <summary>
/// Socket基类(抽象类)
/// 抽象3个方法,初始化Socket(含一个构造),停止,启动方法.
/// 此抽象类为TcpServer与TcpClient的基类,前者实现后者抽象方法
/// </summary>
public abstract class SocketObject
{
public abstract void InitSocket(IPAddress ipaddress, int port);
public abstract void InitSocket(string ipaddress, int port);
public abstract void Start();
public abstract void Stop();
}
}

View File

@ -0,0 +1,733 @@
using System.Configuration;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Net;
using System.Text;
namespace UIStandardWebApi.Common
{
public static class tools
{
#region PING IP是否ping通
/// <summary>
/// IP地址是否ping通
/// </summary>
/// <param name="strIP">IP地址例如“10.8.2.1”</param>
/// <returns></returns>
public static bool PingIp(string strIP)
{
bool bRet = false;
try
{
Ping pingSend = new Ping();
PingReply reply = pingSend.Send(strIP, 1000);
if (reply.Status == IPStatus.Success)
bRet = true;
}
catch (Exception)
{
bRet = false;
}
return bRet;
}
#endregion
#region
public static void AddLog(string logstring)
{
AddLgoToTXT("解析数据.txt", System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"数据记录\" + System.DateTime.Now.ToString("yyyy_MM_dd") + @"\", logstring);
}
#endregion
#region
/// <summary>
/// 文件自动保存
/// </summary>
/// <param name="_file_name">文件名称</param>
/// <param name="path">保存路径</param>
/// <param name="logstring">文件内容</param>
public static void AddLgoToTXT(string _file_name, string path, string logstring)
{
//检查是否存在该路径
if (!System.IO.Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
path = path + _file_name;
//检查该路径下是否存在该文件
if (!System.IO.File.Exists(path))
{
FileStream stream = null;
try
{
stream = System.IO.File.Create(path);
stream.Close();
stream.Dispose();
}
catch (Exception ex)
{
}
finally
{
if (stream != null)
{
stream.Close();
stream.Dispose();
}
}
}
if (!Txt_Used.ContainsKey(path))
{
Txt_Used.Add(path, true);
}
else
{
if (Txt_Used[path])
{
return;
}
else
{
Txt_Used[path] = true;
}
}
FileStream fs = null;
try
{
//[1]创建文件流 文件路径 和枚举类型的文件操作类型
fs = new FileStream(path, FileMode.Append);
//[2]创建写入器
StreamWriter sw = new StreamWriter(fs);
//[3]以流的方式写入数据
sw.Write(logstring);
//[4]关闭写入器
sw.Close();
//[5]关闭文件流
fs.Close();
Txt_Used[path] = false;
}
catch (Exception ex)
{
}
finally
{
if (fs != null)
{
fs.Close();
fs.Dispose();
}
}
}
#endregion
static Dictionary<string, bool> Txt_Used = new Dictionary<string, bool>();
#region TXT文件
public static string ReadFromTXT(string _file_name, string path)
{
//检查是否存在该路径
if (!System.IO.Directory.Exists(path))
return "所选时间段没有系统日志";
path = path + _file_name;
//检查该路径下是否存在该文件
if (!System.IO.File.Exists(path))
return "所选时间段没有系统日志";
//如果文件占用就
if (FileIsInUse(new FileInfo(path)))
return "";
//[1]创建文件流
FileStream fs = new FileStream(path, FileMode.Open);
//【2】创建读取器
//Encoding.Default 读取未知文件是使用default格式
//StreamReader sr = new StreamReader(fs,Encoding.Default);
StreamReader sr = new StreamReader(fs);
//【3】以流的方式读取数据
string txt = sr.ReadToEnd();
//[4]关闭读取器
sr.Close();
//【5】关闭文件流
fs.Close();
return txt;
}
#endregion
#region
static bool FileIsInUse(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
//如果文件被占用,即
//1.文件正在被另一个线程处理
//2.或者正在被另一个线程处理
//3.或者文件不存在
return true;
}
finally
{
if (stream != null)
stream.Close();
}
return false;
}
#endregion
#region CRC校验
private static readonly byte[] aucCRCHi = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40
};
private static readonly byte[] aucCRCLo = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
0x41, 0x81, 0x80, 0x40
};
public static byte[] Crc16(byte[] pucFrame, int usLen)
{
int i = 0;
byte crcHi = 0xFF;
byte crcLo = 0xFF;
UInt16 iIndex = 0x0000;
while (usLen-- > 0)
{
iIndex = (UInt16)(crcLo ^ pucFrame[i++]);
crcLo = (byte)(crcHi ^ aucCRCHi[iIndex]);
crcHi = aucCRCLo[iIndex];
}
return new byte[] { crcLo, crcHi };
}
#endregion
#region 16ASCII
/// <summary>
/// 16进制转字符串ASCII
/// </summary>
/// <param name="hs"></param>
/// <param name="encode"></param>
/// <returns></returns>
public static string HexStringToString(string hs, Encoding encode)
{
StringBuilder strTemp = new StringBuilder();
byte[] b = new byte[hs.Length / 2];
for (int i = 0; i < hs.Length / 2; i++)
{
strTemp.Clear();
strTemp.Append(hs.Substring(i * 2, 2));
b[i] = Convert.ToByte(strTemp.ToString(), 16);
}
return encode.GetString(b);
}
#endregion
#region 16
/// <summary>
/// 字节数组转16进制字符串
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public static string byteToHexStr(byte[] bytes)
{
string returnStr = "";
if (bytes != null)
{
for (int i = 0; i < bytes.Length; i++)
{
returnStr += bytes[i].ToString("X2");
}
}
return returnStr;
}
#endregion
#region 16
/// <summary>
/// 16进制原码字符串转字节数组
/// </summary>
/// <param name="hexString">"AABBCC"或"AA BB CC"格式的字符串</param>
/// <returns></returns>
public static byte[] ConvertHexStringToBytes(string hexString)
{
hexString = hexString.Replace(" ", "");
if (hexString.Length % 2 != 0)
{
throw new ArgumentException("参数长度不正确");
}
byte[] returnBytes = new byte[hexString.Length / 2];
for (int i = 0; i < returnBytes.Length; i++)
{
returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
}
return returnBytes;
}
#endregion
#region 162
/// <summary>
/// //16转2方法
/// </summary>
/// <param name="hexString"></param>
/// <returns></returns>
public static string HexString2BinString(string hexString)
{
try
{
string result = string.Empty;
foreach (char c in hexString)
{
int v = Convert.ToInt32(c.ToString(), 16);
int v2 = int.Parse(Convert.ToString(v, 2));
// 去掉格式串中的空格即可去掉每个4位二进制数之间的空格
result += string.Format("{0:d4} ", v2);
}
return result;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
#endregion
/// <summary>
/// 将传入的byte数组 从指定位置倒置 -- bytetofloat
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
public static float bytetofloat(List<byte> b, int start)
{
return BitConverter.ToSingle(new byte[] { b[start + 3], b[start + 2], b[start + 1], b[start] }, 0);
}
/// <summary>
/// 将传入的byte数组 从指定位置倒置 -- bytetoInt
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
public static int bytetoInt(List<byte> b, int start)
{
return BitConverter.ToInt16(new byte[] { b[start + 1], b[start] }, 0);
}
/// <summary>
/// 将传入的byte数组 -- bytetoUInt
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
public static UInt32 bytetoUInt(List<byte> b, int start)
{
return BitConverter.ToUInt32(new byte[] { b[start], b[start + 1], b[start + 2], b[start + 3] }, 0);
}
/// <summary>
/// 将传入的byte数组 -- bytetoInt
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
public static int bytetoInt32(List<byte> b, int start)
{
return BitConverter.ToInt32(new byte[] { b[start], b[start + 1], b[start + 2], b[start + 3] }, 0);
}
/// <summary>
/// 将传入的byte数组 -- bytetofloat
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
public static float bytetoSingle(List<byte> b, int start)
{
return BitConverter.ToSingle(new byte[] { b[start], b[start + 1], b[start + 2], b[start + 3] }, 0);
}
/// <summary>
/// 计算按位异或校验和(返回校验和值)
/// </summary>
/// <param name="Cmd"></param>
/// <returns></returns>
public static byte GetXOR(byte[] Cmd)
{
byte check = (byte)(Cmd[0] ^ Cmd[1]);
for (int i = 2; i < Cmd.Length; i++)
{
check = (byte)(check ^ Cmd[i]);
}
return check;
}
public static List<bool> O_C(string o_c)
{
o_c = o_c.Trim();
List<bool> result = new List<bool>();
for (int i = 0; i < o_c.Length; i++)
{
if (o_c.Substring(i, 1).Equals("1"))
{
result.Add(true);
}
else if (o_c.Substring(i, 1).Equals("0"))
{
result.Add(false);
}
}
return result;
}
public static List<byte> Q_C(string o_c)
{
o_c = o_c.Trim();
List<byte> result = new List<byte>();
for (int i = o_c.Length - 1; i >= 0; i--)
{
if (o_c.Substring(i, 1).Equals("1"))
{
result.Add(1);
}
else if (o_c.Substring(i, 1).Equals("0"))
{
result.Add(0);
}
}
return result;
}
#region 16ASI码字符串
/// <summary>
/// 将一条十六进制字符串转换为ASCII
/// </summary>
/// <param name="hexstring">一条十六进制字符串</param>
/// <returns>返回一条ASCII码</returns>
public static string HexStringToASCII(string hexstring)
{
byte[] bt = HexStringToBinary(hexstring);
string lin = "";
for (int i = 0; i < bt.Length; i++)
{
lin = lin + bt[i] + " ";
}
string[] ss = lin.Trim().Split(new char[] { ' ' });
char[] c = new char[ss.Length];
int a;
for (int i = 0; i < c.Length; i++)
{
a = Convert.ToInt32(ss[i]);
c[i] = Convert.ToChar(a);
}
string b = new string(c);
return b;
}
/**/
/// <summary>
/// 16进制字符串转换为二进制数组
/// </summary>
/// <param name="hexstring">用空格切割字符串</param>
/// <returns>返回一个二进制字符串</returns>
public static byte[] HexStringToBinary(string hexstring)
{
string[] tmpary = hexstring.Trim().Split(' ');
byte[] buff = new byte[tmpary.Length];
for (int i = 0; i < buff.Length; i++)
{
buff[i] = Convert.ToByte(tmpary[i], 16);
}
return buff;
}
#endregion
#region
private static Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
/// <summary>
/// 获取配置文件
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static string GetAppSetting(string key)
{
if (System.Configuration.ConfigurationManager.AppSettings.AllKeys.Contains(key))
{
string value = config.AppSettings.Settings[key].Value;
return value;
}
else
{
return null;
}
}
/// <summary>
/// 更新配置文件信息
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public static void UpdateAppSettings(string key, string value)
{
if (GetAppSetting(key) == value) //如果写入的配置文件和之前一致 就不写入了
return;
if (System.Configuration.ConfigurationManager.AppSettings.AllKeys.Contains(key))
{
config.AppSettings.Settings[key].Value = value;
config.Save(ConfigurationSaveMode.Modified);
System.Configuration.ConfigurationManager.RefreshSection("appSettings");//刷新数据
}
else
{
Console.WriteLine("当前节点不存在!");
}
}
#endregion
#region Telnet
public static bool TelnetPort(string ip, int port)
{
if (checkPingEnable(ip))
{
if (checkPortEnable(ip, port))
{
return true;
}
}
return false;
}
//检查是否ping通
public static bool checkPingEnable(string _ip)
{
bool _isEnable = false;
try
{
Ping pingSender = new Ping();
PingReply reply = pingSender.Send(_ip, 120);//第一个参数为ip地址第二个参数为ping的时间
if (reply.Status == IPStatus.Success)
{
_isEnable = true;
}
else
{
_isEnable = false;
}
}
catch (Exception)
{
_isEnable = false;
}
return _isEnable;
}
/// <summary>
/// telnet port
/// </summary>
/// <param name="_ip"></param>
/// <param name="_port"></param>
/// <returns></returns>
public static bool checkPortEnable(string _ip, int _port)
{
//将IP和端口替换成为你要检测的
string ipAddress = _ip;
int portNum = _port;
IPAddress ip = IPAddress.Parse(ipAddress);
IPEndPoint point = new IPEndPoint(ip, portNum);
bool _portEnable = false;
try
{
using (Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
sock.Connect(point);
//Console.WriteLine("连接{0}成功!", point);
sock.Close();
_portEnable = true;
}
}
catch (SocketException e)
{
//Console.WriteLine("连接{0}失败", point);
_portEnable = false;
}
return _portEnable;
}
#endregion
#region
/// <summary>
///设置线程工作的空间
/// </summary>
/// <param name="process">线程</param>
/// <param name="minSize">最小空间</param>
/// <param name="maxSize">最大空间</param>
/// <returns></returns>
[System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
private static extern int SetProcessWorkingSetSize(IntPtr process, int minimumWorkingSetSize, int maximumWorkingSetSize);
public static void ClearMemory(object o)
{
GC.Collect();
GC.SuppressFinalize(o);
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
}
}
#endregion
public static byte[] intoBytes(int value)
{
byte[] src = new byte[4]
{
(byte)((value) & 0xFF),
(byte)((value >> 8) & 0xFF),
(byte)((value >> 16) & 0xFF),
(byte)(value >> 24 & 0xFF)
};
return src;
}
public static byte[] shortoBytes(int value)
{
byte[] src = new byte[2]
{
(byte)((value) & 0xFF),
(byte)((value >> 8) & 0xFF)
};
return src;
}
/// <summary>
/// TcpClient检测
/// </summary>
/// <param name="ip">ip地址</param>
/// <param name="port">端口号</param>
public static bool TcpClientCheck(string ip, int port)
{
IPAddress ipa = IPAddress.Parse(ip);
IPEndPoint point = new IPEndPoint(ipa, port);
TcpClient tcp = null;
try
{
tcp = new TcpClient();
tcp.Connect(point);
//Console.WriteLine("端口打开");
return true;
}
catch (Exception ex)
{
//Console.WriteLine("计算机端口检测失败,错误消息为:" + ex.Message);
return false;
}
finally
{
if (tcp != null)
{
tcp.Close();
}
}
}
/// <summary>
/// Socket检测
/// </summary>
/// <param name="ip">ip地址</param>
/// <param name="port">端口号</param>
public static bool SocketCheck(string ip, int port)
{
Socket sock = null;
try
{
IPAddress ipa = IPAddress.Parse(ip);
IPEndPoint point = new IPEndPoint(ipa, port);
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Connect(point);
//Console.WriteLine("端口打开");
return true;
}
catch (SocketException ex)
{
//Console.WriteLine("计算机端口检测失败,错误消息为:" + ex.Message);
return false;
}
finally
{
if (sock != null)
{
sock.Close();
sock.Dispose();
}
}
}
//获取当前程序运行路径
private static string Save_Path = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"数据记录\";
public static void Logging(string message)
{
AddLgoToTXT("Log.txt", Save_Path + System.DateTime.Now.ToString("yyyy_MM_dd") + @"\", System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " ---- " + message + "\r\n");
}
}
}

View File

@ -0,0 +1,35 @@
using Microsoft.AspNetCore.Mvc;
using UIStandardWebApi.WebCore.SwaggerExtend;
namespace UIStandardWebApi.Controllers
{
[ApiController]
[ApiExplorerSettings(IgnoreApi = false, GroupName = nameof(ApiVersions.V1))]
[Route("api/[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}

View File

@ -0,0 +1,69 @@
using UIStandardWebApi.SqlSuggar;
using UIStandardWebApi.Utility.RegisterExt;
using UIStandardWebApi.WebCore.AutoMapExtend;
using UIStandardWebApi.WebCore.CorsExtend;
using UIStandardWebApi.WebCore.SwaggerExtend;
namespace UIStandardWebApi
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
//服务注册
builder.RegistService();
//配置解决中文乱码等问题
builder.RegistControllers();
//Swagger
builder.Services.AddSwaggerExt("软件标准化Api文档", "软件标准化Api文档");
//Automapper注册
builder.Services.AddAutoMapper(typeof(AutoMapperConfigs));
builder.Services.AddMemoryCache();
//跨域
builder.Services.AddCorsExt();
builder.InitSqlSugar(); //注册SqlSugar
if (builder.Configuration["IsInitDatabase"] == "1")
{
builder.InitDatabase();
}
var app = builder.Build();
//使用Swagger
app.UseSwaggerExt("软件标准化Api文档");
//使用跨域策略
app.UseCorsExt();
//映射默认的 MVC 路由
app.MapControllers();
//让应用程序把 HTTP 请求重定向到 HTTPS 请求,以此增强应用程序的安全性
app.UseHttpsRedirection();
// 使用身份验证中间件
app.UseAuthentication();
// 使用授权中间件
app.UseAuthorization();
app.Run();
}
}
}

View File

@ -0,0 +1,41 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:21734",
"sslPort": 44376
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5047",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7224;http://localhost:5047",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,53 @@
using SqlSugar;
namespace UIStandardWebApi.SqlSuggar
{
/// <summary>
/// 数据库配置文件映射实体对象,专用作读取配置文件使用
/// </summary>
public class CustomConnectionConfig
{
/// <summary>
/// 初始化从库链接--多个从库--集合
/// </summary>
public CustomConnectionConfig()
{
SlaveConnectionConfigs = new List<CustomSlaveConnectionConfig>();
}
/// <summary>
/// 主库链接
/// </summary>
public string? ConnectionString
{
get;
set;
}
/// <summary>
/// 从库链接--多个从库--集合
/// </summary>
public List<CustomSlaveConnectionConfig> SlaveConnectionConfigs { get; set; }
}
/// <summary>
/// 从库链接配置文件读取
/// </summary>
public class CustomSlaveConnectionConfig : SlaveConnectionConfig
{
private int _CustomHitRate;
/// <summary>
///读取配置文件中,从库数据的权重数据
/// </summary>
public int CustomHitRate
{
get { return _CustomHitRate; }
set
{
HitRate = value;
_CustomHitRate = value;
}
}
}
}

View File

@ -0,0 +1,46 @@
using SqlSugar;
using System.Reflection;
using UIStandardWebApi.Common;
namespace UIStandardWebApi.SqlSuggar
{
/// <summary>
/// 是否初始化数据库
/// </summary>
public static class InitDatabaseExt
{
/// <summary>
/// 是否初始化数据库
/// </summary>
/// <param name="builder"></param>
/// <exception cref="Exception"></exception>
public static void InitDatabase(this WebApplicationBuilder builder)
{
string? connectionString = builder.Configuration.GetConnectionString("ConnectionString");
if (string.IsNullOrWhiteSpace(connectionString))
{
throw new Exception("请配置数据库链接字符串~");
}
ConnectionConfig connection = new ConnectionConfig()
{
DbType = DbType.SqlServer,
IsAutoCloseConnection = true,
ConnectionString = connectionString
};
using (SqlSugarClient client = new SqlSugarClient(connection))
{
client.DbMaintenance.CreateDatabase();
Assembly assembly = Assembly.LoadFile(Path.Combine(AppContext.BaseDirectory, "UIStandardWebApi.Entity.dll"));
Type[] typeArray = assembly.GetTypes()
.Where(t => !t.Name.Equals("Sys_BaseModel") && t.Namespace.Equals("UIStandardWebApi.Entity"))
.ToArray();
client.CodeFirst.InitTables(typeArray);
}
}
}
}

View File

@ -0,0 +1,70 @@
using SqlSugar;
namespace UIStandardWebApi.SqlSuggar
{
/// <summary>
/// 初始化SqlSugar
/// </summary>
public static class InitSqlSugarExt
{
/// <summary>
/// 初始化SqlSugar
/// </summary>
/// <param name="builder"></param>
public static void InitSqlSugar(this WebApplicationBuilder builder)
{
CustomConnectionConfig customConnectionConfig = new CustomConnectionConfig();
builder.Configuration.Bind("ConnectionStrings", customConnectionConfig);
builder.Services.AddTransient<ISqlSugarClient>(s =>
{
ConnectionConfig connection = new ConnectionConfig()
{
ConnectionString = customConnectionConfig.ConnectionString,
DbType = DbType.SqlServer,
IsAutoCloseConnection = true,
InitKeyType = InitKeyType.Attribute,
SlaveConnectionConfigs = customConnectionConfig.SlaveConnectionConfigs.Select(c => new SlaveConnectionConfig() { ConnectionString = c.ConnectionString, HitRate = c.CustomHitRate }).ToList()
};
SqlSugarClient client = new SqlSugarClient(connection);
client.Aop.OnLogExecuting = (s, p) =>
{
//Console.WriteLine("*******************************************************************************************");
//Console.WriteLine($"OnLogExecuting:输出Sql语句:{s} || 参数为:{string.Join(",", p.Select(p => p.Value))}");
};
client.Aop.DataExecuting = (s, p) =>
{
if (p.OperationType.Equals(DataFilterType.InsertByObject) && "CreateTime".Equals(p.EntityColumnInfo.DbColumnName))
{
p.SetValue(DateTime.Now);
}
if (p.OperationType.Equals(DataFilterType.UpdateByObject) && "ModifyTime".Equals(p.EntityColumnInfo.DbColumnName))
{
p.SetValue(DateTime.Now);
}
};
client.Aop.OnLogExecuted = (s, p) =>
{
//Console.WriteLine("*******************************************************************************************");
//Console.WriteLine($"OnLogExecuted:输出Sql语句:{s} || 参数为:{string.Join(",", p.Select(p => p.Value))}");
};
client.Aop.OnError = e =>
{
Console.WriteLine("*******************************************************************************************");
Console.WriteLine($"OnError:Sql语句执行异常:{e.Message}");
};
return client;
});
//初始化开启服务器
//SocketStatic.socketListening.OpenServer(8899);
}
}
}

View File

@ -0,0 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.14" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.14" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="8.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.188" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\UIStandardWebApi.Entity\UIStandardWebApi.Entity.csproj" />
<ProjectReference Include="..\UIStandardWebApi.WebCore\UIStandardWebApi.WebCore.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Utility\AuthorizationExtend\" />
<Folder Include="Utility\Filters\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,53 @@
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json;
using System.Text.Encodings.Web;
using System.Text.Unicode;
using UIStandardWebApi.Common.JwtService;
namespace UIStandardWebApi.Utility.RegisterExt
{
/// <summary>
/// 服务注册
/// </summary>
public static class RegistServiceExtension
{
/// <summary>
/// 注册服务层
/// </summary>
/// <param name="builder"></param>
public static void RegistService(this WebApplicationBuilder builder)
{
//builder.Services.AddTransient<ISys_SamplingService, Sys_SamplingService>();
builder.Services.Configure<JWTTokenOptions>(builder.Configuration.GetSection("JWTTokenOptions"));
}
/// <summary>
/// AddControllers 相关
/// </summary>
/// <param name="builder"></param>
public static void RegistControllers(this WebApplicationBuilder builder)
{
builder.Services.AddControllers(option =>
{
}).AddNewtonsoftJson(options =>
{
//配置返回JSON首字母问题以及格式 nuget引入Microsoft.AspNetCore.Mvc.NewtonsoftJson
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
//options.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();//设置JSON返回格式同model一致
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();//设置JSON返回格式首字母小写
}).AddJsonOptions(options =>
{
//配置解决中文乱码问题
options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
});
}
}
}

View File

@ -0,0 +1,13 @@
namespace UIStandardWebApi
{
public class WeatherForecast
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@ -0,0 +1,28 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"IsInitDatabase": "0",
"Socket": {
"ip": "192.168.1.254",
"port": "8899"
},
"ConnectionStrings": {
"ConnectionString": "Data Source = NB10920;Initial Catalog=InSituLaboratoryWeb;User ID=sa;Password=zttZTT123;MultipleActiveResultSets=true",
"DbType": 1
},
"JWTTokenOptions": {
"Audience": "http://localhost:5200",
"Issuer": "http://localhost:5200",
"SecurityKey": "我是一个秘钥秘钥长度尽量保证在16个字符以上"
},
"StaticFileAddress": "/root/file"
}