nuget包

1.AutoMapper

一次配置:只需在一个地方定义对象的转换规则。

直接调用:用 mapper.Map 方法即可完成所有对象的转换。

节省代码:不用每次都写重复的赋值逻辑。

集中管理:所有转换规则都在一个地方,修改时不需要到处找。

清晰且易维护:映射逻辑独立、集中,业务代码更简洁。

1-安装AutoMapper 2-配置AutoMapper映射规则,使用

//自动映射
// AutoMapper 配置:一次定义 User 到 UserDto 的映射规则
public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<User, UserDto>()
            .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => $"{src.FirstName} {src.LastName}"));
    }
}
// 初始化 AutoMapper
var config = new MapperConfiguration(cfg => cfg.AddProfile<AutoMapperProfile>());
var mapper = config.CreateMapper();
// 示例数据
User user = new User { Id = 1, FirstName = "John", LastName = "Doe", Email = "john.doe@example.com" };
// 自动映射
UserDto dto = mapper.Map<UserDto>(user);
// 打印结果
Console.WriteLine($"{dto.FullName}, {dto.Email}");
//手动映射代码
public UserDto ConvertToDto(User user)
{
    return new UserDto
    {
        Id = user.Id,
        FullName = $"{user.FirstName} {user.LastName}", // 手动拼接
        Email = user.Email
    };
}
// 示例使用
User user = new User { Id = 1, FirstName = "John", LastName = "Doe", Email = "john.doe@example.com" };
UserDto dto = ConvertToDto(user);
// 打印结果
Console.WriteLine($"{dto.FullName}, {dto.Email}");
//作用: 定义从 生产过站信息接口请求体 类型到 PassStation 类型的映射规则。
//CreateMap<TSource, TDestination>: 表示将源类型 生产过站信息接口请求体 的属性映射到目标类型 PassStation 的属性。
var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<生产过站信息接口请求体, PassStation>();
});
//基于配置创建一个 mapper 对象
var mapper = config.CreateMapper();
//将 data(类型为 生产过站信息接口请求体 的对象)转换为 PassStation 类型的对象。
PassStation entity = mapper.Map<PassStation>(data);
//使用 AutoMapper 将 MaterialBind 映射到 MaterialBindInfo,目的是让数据适配 UI 层。
var config = new MapperConfiguration(cfg =>
{
                cfg.CreateMap<MaterialBind, MaterialBindInfo>();
});
var mapper = config.CreateMapper();
MaterialBindInfo materialBindInfo = mapper.Map<MaterialBindInfo>(mb);
materialBindInfo.data = new BindingList<MaterialBindData>();

2.Microsoft.AspNetCore.SignalR.Common

.NET Core中使用 SignalR 可以显著简化实时通讯的实现。

通过 SignalR向客户端推送系统更新、警报或其他实时数据。

实现多人同时编辑或交互的功能。

1-安装Microsoft.AspNetCore.SignalR.Common包 2-添加SignalR服务

// 添加 SignalR 服务
builder.Services.AddSignalR(options =>
{
    options.EnableDetailedErrors = true;  // 启用详细错误信息
});
...
// 映射 SignalR Hub
app.MapHub<LmesHub>("/Hub");

3-创建 SignalR Hub

public class LmesHub : Hub
{
    public async Task SendMessage(string? user, string? message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}

4-客户端安装Microsoft.AspNetCore.SignalR.Client

5-使用 HubConnection 类来建立与 SignalR Hub 的连接。

//HubConnectionBuilder用于构建一个 HubConnection 实例
//.WithAutomaticReconnect()启用自动重连功能,当客户端断开时,它会尝试重新连接到服务器。
//.WithUrl()配置 SignalR 服务的地址
服务器hub = new HubConnectionBuilder()
 .WithAutomaticReconnect()
 .WithUrl($"{系统参数.设置.Lmes连接参数.LMES地址}Hub") // 服务器地址
 .Build();
//注册接受消息的方法
//当服务器调用 Clients.All.SendAsync("统一初始化") 时,客户端会执行回调函数。
//notificationManager.ShowAsync(...)异步显示通知,用于向用户提示某些操作或状态。
服务器hub.On("统一初始化", () =>
{
    _ = notificationManager.ShowAsync(new NotificationContent
    {
        Title = "收到初始化物料的请求",
        Message = $"收到初始化物料的请求",
        Type = NotificationType.Information
    }, areaName: "WindowArea");
    日志写入.写入($"收到初始化物料的请求");
    菜单_1_Click(null, null);
});
//启动SignlR连接
try
{
    await 服务器hub.StartAsync();
    _ = notificationManager.ShowAsync(new NotificationContent
    {
        Title = "hub连接成功",
        Message = $"hub连接成功",
        Type = NotificationType.Success
    }, areaName: "WindowArea");
}
catch (Exception ex)
{
    _ = notificationManager.ShowAsync(new NotificationContent
    {
        Title = "hub连接失败",
        Message = $"{ex}",
        Type = NotificationType.Error
    }, areaName: "WindowArea");
}
// 发送消息的按钮点击事件
// 通过 SignalR Hub 发送消息
await 服务器hub.InvokeAsync("请求切换信号表", temp.站点类别, str);

3.Npgsql.EntityFrameworkCore.PostgreSQL

用于在 .NET 项目中通过 Entity Framework Core 与 PostgreSQL 数据库交互。它为 PostgreSQL 数据库提供了 Entity Framework Core 的功能支持,允许开发人员使用 EF Core 的 Code-First 和 Database-First 模型,以及 LINQ 查询来操作 PostgreSQL 数据。

4.Swashbuckle.AspNetCore

ASP.NET Core 应用中轻松集成 Swagger/OpenAPI 文档生成和用户界面测试功能。它帮助开发者更高效地记录和调试 Web API。

5.System.IdentityModel.Tokens.Jwt

private async Task<string> GenerateToken(string username)
{
    var findkey = await 数据库.设置.FirstOrDefaultAsync(s => s.参数名 == "登录验证key");
    if (findkey is null)
    {
        //使用 GenerateRandomKey 方法生成随机密钥(假定此方法已经实现)
        findkey = new() { 参数名 = "登录验证key", 值 = GenerateRandomKey() };
        await 数据库.设置.AddAsync(findkey);
    }
    //使用 JwtSecurityTokenHandler 创建 JWT 令牌。
    var tokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.UTF8.GetBytes(findkey.值);
    var tokenDescriptor = new SecurityTokenDescriptor
    {
        //配置 ClaimsIdentity,为令牌添加一个声明,表明用户名。
        Subject = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, username) }),
        //设置令牌有效期为 1 小时。
        Expires = DateTime.UtcNow.AddHours(1),
        //使用对称密钥(HMAC SHA-256)为令牌签名。
        SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
    };
​
    var token = tokenHandler.CreateToken(tokenDescriptor);
    //使用 WriteToken 将生成的令牌序列化为字符串返回。
    return tokenHandler.WriteToken(token);
}

Api

在Program.cs中添加

// Add services to the container.
builder.Services.AddHttpClient<HttpAPI>();

HttpAPI.cs

 public class HttpAPI
 {
     //HttpClient 被实例化并配置了请求头,如 appId、appKey 和 Content-Type。
     private readonly HttpClient httpClient = new HttpClient();
​
     //构造函数
     public HttpAPI(string 基地址, string appId, string appKey)
     {
         httpClient.DefaultRequestHeaders.Add("appId", appId);
         httpClient.DefaultRequestHeaders.Add("appKey", appKey);
         httpClient.DefaultRequestHeaders.Add("Content-Type", "application/json");
     }
​
     //PostAsync 是一个泛型方法,用于发送 POST 请求。它将 body 转换为 JSON 格式并发送到指定的 地址。
     private async Task<T?> PostAsync<T>(string 地址, object body)
     {
         var re = await httpClient.PostAsJsonAsync(地址, body);
         //如果请求失败(IsSuccessStatusCode == false),会抛出一个异常,包含错误的状态码和响应内容。
         if (re.IsSuccessStatusCode == false)
         {
             var errre = re.Content.ReadAsStringAsync();
             throw new Exception($"{re.StatusCode},{errre}");
         }
         //如果请求成功,方法会将响应内容反序列化为类型 T 并返回。
         return await re.Content.ReadFromJsonAsync<T>();
     }
​
     public async Task<工厂模型数据接口返回体?> 工厂模型数据接口(工厂模型数据接口请求体 请求数据)
     {
         return await PostAsync<工厂模型数据接口返回体>(全局变量.总Mes连接信息设置.工厂模型数据接口地址, 请求数据);
     }

http请求,前后端路由格式要匹配

var response = await _httpClient.DeleteAsync($"api/时间管控/根据id删除固化时间设置/{要删除的设置.id}");

[HttpDelete("根据id删除固化时间设置/{id}")] // 修改路由格式 public async Task<ActionResult<固化时间设置类>> 删除固化时间设置(int id)