Files
tnb.server/apihost/Tnb.API.Entry/Startup.cs
2023-03-13 15:00:34 +08:00

242 lines
7.6 KiB
C#
Raw 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 JNPF.API.Entry.Handlers;
using JNPF.Common.Cache;
using JNPF.Common.Core.Filter;
using JNPF.DatabaseAccessor;
using JNPF.EventHandler;
using JNPF.JsonSerialization;
using JNPF.Message.Handlers;
using JNPF.TaskScheduler.Interfaces.TaskScheduler;
using JNPF.UnifyResult;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json;
using Senparc.CO2NET.RegisterServices;
using Senparc.CO2NET;
using Senparc.Weixin;
using Senparc.Weixin.Entities;
using Senparc.Weixin.RegisterServices;
using SqlSugar;
using IGeekFan.AspNetCore.Knife4jUI;
using JNPF.SpecificationDocument;
using JNPF.Logging;
using System.Xml;
using System;
using System.Text;
using Top.Api;
namespace JNPF.API.Entry;
public class Startup : AppStartup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddConsoleFormatter(option =>
{
option.MessageFormat = LoggerConsoleFormat;
});
// SqlSugar
services.SqlSugarConfigure();
// Jwt处理程序
services.AddJwt<JwtHandler>(enableGlobalAuthorize: true);
// 跨域
services.AddCorsAccessor();
// 注册EventBus服务
services.AddEventBus(options =>
{
//// 创建连接工厂
//var factory = new RabbitMQ.Client.ConnectionFactory
//{
// // 设置主机名
// HostName = "192.168.0.232",
// // 用户名
// UserName = "jnpf",
// // 密码
// Password = "jnpf@2019",
//};
//// 创建默认内存通道事件源对象可自定义队列路由key比如这里是 eventbus
//var rbmqEventSourceStorer = new RabbitMQEventSourceStorer(factory, "eventbus", 3000);
//// 替换默认事件总线存储器
//options.ReplaceStorer(serviceProvider =>
//{
// return rbmqEventSourceStorer;
//});
options.UseUtcTimestamp = false;
// 不启用事件日志
options.LogEnabled = false;
// 事件执行器(失败重试)
options.AddExecutor<RetryEventHandlerExecutor>();
});
// 注册远程请求
services.AddRemoteRequest();
services.AddConfigurableOptions<CacheOptions>();
services.AddConfigurableOptions<ConnectionStringsOptions>();
services.AddConfigurableOptions<TenantOptions>();
services.AddControllers()
.AddMvcFilter<RequestActionFilter>()
.AddInjectWithUnifyResult<RESTfulResultProvider>()
.AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null)
.AddNewtonsoftJson(options =>
{
// 默认命名规则
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
// 设置时区为 UTC
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
// 格式化json输出的日期格式
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
// 忽略空值
// options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
// 忽略循环引用
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
// 格式化json输出的日期格式为时间戳
options.SerializerSettings.Converters.Add(new NewtonsoftDateTimeJsonConverter());
});
// 配置Nginx转发获取客户端真实IP
// 注1如果负载均衡不是在本机通过 Loopback 地址转发请求的一定要加上options.KnownNetworks.Clear()和options.KnownProxies.Clear()
// 注2如果设置环境变量 ASPNETCORE_FORWARDEDHEADERS_ENABLED 为 True则不需要下面的配置代码
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.All;
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
// 视图引擎
services.AddViewEngine();
// 任务调度
services.AddTaskScheduler();
// 脱敏词汇检测
services.AddSensitiveDetection();
// WebSocket服务
services.AddWebSocketManager();
// 微信
services.AddSenparcGlobalServices(App.Configuration) // Senparc.CO2NET 全局注册
.AddSenparcWeixinServices(App.Configuration); // Senparc.Weixin 注册如果使用Senparc.Weixin SDK则添加
services.AddSession();
services.AddMemoryCache(); // 使用本地缓存必须添加
// 日志监听
// services.AddMonitorLogging(options =>
//{
// options.IgnorePropertyNames = new[] { "Byte" };
// options.IgnorePropertyTypes = new[] { typeof(byte[]) };
//});
services.AddFileLogging(options =>
{
options.MessageFormat = LoggerFileFormat;
options.FileNameRule = fileName => string.Format(fileName, DateTime.Now); // 每天创建一个文件
options.HandleWriteError = (writeError) => // 写入失败时启用备用文件
{
writeError.UseRollbackFileName(Path.GetFileNameWithoutExtension(writeError.CurrentFileName) + "-oops" + Path.GetExtension(writeError.CurrentFileName));
};
});
services.AddUnitOfWork<SqlSugarUnitOfWork>();
services.OSSServiceConfigure();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSchedule();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider, IOptions<SenparcSetting> senparcSetting, IOptions<SenparcWeixinSetting> senparcWeixinSetting)
{
// 添加状态码拦截中间件
app.UseUnifyResultStatusCodes();
// app.UseHttpsRedirection(); // 强制https
app.UseStaticFiles();
#region
IRegisterService register = RegisterService.Start(senparcSetting.Value).UseSenparcGlobal();//启动 CO2NET 全局注册,必须!
register.UseSenparcWeixin(senparcWeixinSetting.Value, senparcSetting.Value);//微信全局注册,必须!
#endregion
app.UseWebSockets();
app.UseRouting();
app.UseCorsAccessor();
app.UseAuthentication();
app.UseAuthorization();
app.UseKnife4UI(options =>
{
options.RoutePrefix = "newapi"; // 配置 Knife4UI 路由地址,现在是 /newapi
foreach (var groupInfo in SpecificationDocumentBuilder.GetOpenApiGroups())
{
options.SwaggerEndpoint("/" + groupInfo.RouteTemplate, groupInfo.Title);
}
});
app.UseInject(string.Empty);
app.MapWebSocketManager("/api/message/websocket", serviceProvider.GetService<IMHandler>());
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
});
serviceProvider.GetRequiredService<ITimeTaskService>().StartTimerJob();
}
const string DATEFORMAT = "HH:mm:ss.fff";
private string LoggerLevelName(LogLevel level)
{
return level switch
{
LogLevel.Trace => "Trace",
LogLevel.Debug => "Debug",
LogLevel.Information => "Info",
LogLevel.Warning => "Warn",
LogLevel.Error => "Error",
LogLevel.Critical => "Crit",
_ => "None"
};
}
private string LoggerFileFormat(LogMessage msg)
{
return $"{LoggerLevelName(msg.LogLevel)} {msg.LogDateTime.ToString(DATEFORMAT)} {msg.ThreadId}# {msg.Message}";
}
private string LoggerConsoleFormat(LogMessage msg)
{
var fclr = msg.LogLevel switch
{
LogLevel.Warning => "\u001b[1m\u001b[33m",
LogLevel.Error => "\u001b[1m\u001b[31m",
_ => "\u001b[39m\u001b[22m"
};
return $"{fclr}{LoggerLevelName(msg.LogLevel)}\u001b[49m \u001b[36m{msg.LogDateTime.ToString(DATEFORMAT)}\u001b[49m \u001b[39m\u001b[22m{msg.ThreadId}#\u001b[49m {fclr}{msg.Message}\u001b[49m";
}
}