2025-11-13 15:31:08 +08:00

199 lines
8.4 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using AspNetCoreRateLimit;
using Infrastructure.Converter;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.FileProviders;
using NLog.Web;
using System.Text.Json;
using DOAN.Admin.WebApi.Extensions;
using DOAN.Common.Cache;
using DOAN.Infrastructure.WebExtensions;
using DOAN.ServiceCore.Signalr;
using DOAN.ServiceCore.SqlSugar;
using Infrastructure;
using System.Text;
using DOAN.Common.SocketHelper;
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseNLog();
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
//注入HttpContextAccessor TODO 这地方就是配置httpcontext https://blog.csdn.net/iqifenxia/article/details/121740805
//builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddHttpContextAccessor();
/*
在ASP.NET Core中`IHttpContextAccessor`是用于访问HTTP请求上下文的接口而`HttpContextAccessor`是`IHttpContextAccessor`接口的一个默认实现。
区别在于:
1. `Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>()`会将`HttpContextAccessor`注册为`IHttpContextAccessor`接口的实现并使用单例模式singleton将实例注册到应用程序中。这意味着在整个应用程序生命周期中只会有一个`HttpContextAccessor`实例被创建并共享。
2. `Services.AddHttpContextAccessor()`是ASP.NET Core提供的一种快捷方法会将`HttpContextAccessor`注册为`IHttpContextAccessor`接口的默认实现并采用Scoped生命周期。Scoped生命周期意味着在同一个请求范围内每次请求都会创建一个新的`HttpContextAccessor`实例,并在请求结束时销毁。
通常建议使用`Services.AddHttpContextAccessor()`来注册`HttpContextAccessor`因为它是ASP.NET Core的标准做法而且会自动处理实例的生命周期管理。
希望这个解释对您有帮助!如果您有任何其他问题,请随时告诉我。
*/
// 跨域配置
builder.Services.AddCors(builder.Configuration);
// 显示logo
builder.Services.AddLogo();
//消除Error unprotecting the session cookie警告
builder.Services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "DataProtection"));
//普通验证码
builder.Services.AddCaptcha(builder.Configuration);
//IPRatelimit
builder.Services.AddIPRate(builder.Configuration);
//builder.Services.AddSession();
//绑定整个对象到Model上
builder.Services.Configure<OptionsSetting>(builder.Configuration);
//jwt 认证
builder.Services.AddJwt();
//配置文件
builder.Services.AddSingleton(new AppSettings(builder.Configuration));
//app服务注册
builder.Services.AddAppService();
//开启计划任务
builder.Services.AddTaskSchedulers();
// 注册 SocketGatewayServer 为 Singleton单例整个应用生命周期一个实例
builder.Services.AddSingleton<SocketGatewayServer>(provider =>
{
var server = new SocketGatewayServer("192.168.50.163", 4021); // 你可以按需修改 IP 和端口
server.Start(); // 项目启动时立即启动监听
//server.StartReceiving();
return server;
});
// 如果你还需要在后台启动接收线程,也可以在这儿调用 StartReceiving()
// 不过也可以选择在首次发送数据前再启动,看你的实际需求
//builder.Services.BuildServiceProvider().GetService<SocketGatewayServer>()?.StartReceiving();
//注册REDIS 服务
var openRedis = builder.Configuration["RedisServer:open"];
if (openRedis == "1")
{
RedisServer.Initalize();
}
builder.Services.AddMvc(options =>
{
options.Filters.Add(typeof(GlobalActionMonitor));//全局注册 过滤器 这边就是 The paramter field is required. | The partnumber field is required. | The workstation field is required."
})
.AddJsonOptions(options =>
{
//options.JsonSerializerOptions.NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString;
options.JsonSerializerOptions.WriteIndented = true;
options.JsonSerializerOptions.Converters.Add(new JsonConverterUtil.DateTimeConverter());
options.JsonSerializerOptions.Converters.Add(new JsonConverterUtil.DateTimeNullConverter());
options.JsonSerializerOptions.Converters.Add(new StringConverter());
//PropertyNamingPolicy属性用于前端传过来的属性的格式策略目前内置的仅有一种策略CamelCase
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
//options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;//属性可以忽略大小写格式,开启后性能会降低
});
//注入SignalR实时通讯默认用json传输
builder.Services.AddSignalR()
.AddJsonProtocol(options =>
{
options.PayloadSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});
builder.Services.AddSwaggerConfig();
builder.Services.AddDirectoryBrowser();
var app = builder.Build();
//全局配置
InternalApp.ServiceProvider = app.Services;
InternalApp.Configuration = builder.Configuration;
InternalApp.WebHostEnvironment = app.Environment;
//初始化db和 配置sqlsugar 然后注入IOC容器然后AOP配置
builder.Services.AddDb(app.Environment);
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
//使用全局异常中间件
app.UseMiddleware<GlobalExceptionMiddleware>();
//请求头转发
//ForwardedHeaders中间件会自动把反向代理服务器转发过来的X-Forwarded-For客户端真实IP以及X-Forwarded-Proto客户端请求的协议自动填充到HttpContext.Connection.RemoteIPAddress和HttpContext.Request.Scheme中这样应用代码中读取到的就是真实的IP和真实的协议了不需要应用做特殊处理。
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedFor | Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedProto
});
app.Use((context, next) =>
{
//设置可以多次获取body内容
context.Request.EnableBuffering();
if (context.Request.Query.TryGetValue("access_token", out var token))
{
context.Request.Headers.Add("Authorization", $"Bearer {token}");
}
return next();
});
//开启访问静态文件/wwwroot目录文件要放在UseRouting前面
var fileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.WebRootPath, "device"));
var requestPath = "/devices";
// Enable displaying browser links.
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(InternalApp.Configuration.GetSection("Upload").GetSection("rootDirectory").Get<string>())
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
//开启路由访问
app.UseRouting();
app.UseCors("Policy");//要放在app.UseEndpoints前。
//app.UseHttpsRedirection();
// 认证 这意味着对于每一个进入应用的HTTP请求框架都会尝试从请求中提取身份验证信息如JWT token、cookies或其他身份验证机制提供的信息并根据这些信息来创建或更新当前用户的身份信息ClaimsPrincipal。如果请求中包含了有效的身份验证凭据那么用户将被认为是已认证的。
app.UseAuthentication();
//授权 在app.UseAuthentication(); 之后调用的 app.UseAuthorization(); 则是启用授权功能。当授权中间件被调用时,它会检查请求上的[Authorize] 属性或其他策略,以确定用户是否有权限访问特定的资源或执行特定的操作。
app.UseAuthorization(); //授权
//开启缓存
app.UseResponseCaching();
if (builder.Environment.IsProduction())
{
//恢复/启动任务
app.UseAddTaskSchedulers();
}
//使用swagger
app.UseSwagger();
//启用客户端IP限制速率
app.UseIpRateLimiting();
app.UseRateLimiter();
//设置socket连接
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<MessageHub>("/msgHub"); // ChatHub 是你自定义的 Hub 类名
endpoints.MapHub<PDAMessageHub>("/pdaHub");
});
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapControllers();
app.Run();