199 lines
8.4 KiB
C#
199 lines
8.4 KiB
C#
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(); |