You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

269 lines
10 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using Admin.Core.Common;
using Admin.Core.Extensions;
using Admin.Core.IService.ISys;
using Admin.Core.Plc;
using Admin.Core.RunPlc;
using Admin.Core.Tasks;
using Autofac;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
namespace Admin.Core.Api
{
/// <summary>
/// Startup
/// </summary>
public class Startup
{
/// <summary>
/// Startup
/// </summary>
/// <param name="configuration"></param>
/// <param name="env"></param>
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
Configuration = configuration;
Env = env;
}
/// <summary>
/// IConfiguration
/// </summary>
public IConfiguration Configuration { get; }
/// <summary>
/// 环境信息:开发/生产
/// </summary>
public IWebHostEnvironment Env { get; }
/// <summary>
/// This method gets called by the runtime. Use this method to add services to the container.
/// </summary>
/// <param name="services"></param>
public void ConfigureServices(IServiceCollection services)
{
//Appsettings
services.AddSingleton(new Appsettings(Configuration));
//日志文件目录
services.AddSingleton(new LogLock(Env.ContentRootPath));
//jwt或Ids4权限方案
Permissions.IsUseIds4 = Appsettings.app(new string[] { "Startup", "IdentityServer4", "Enabled" }).ObjToBool();
// 确保从认证中心返回的ClaimType不被更改不使用Map映射
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
//Memory缓存
services.AddMemoryCacheSetup();
//Swagger
services.AddSwaggerSetup();
//Sqlsugar数据库模型查询
services.AddSqlsugarSetup();
//AutoMapper
services.AddAutoMapperSetup();
//跨域
services.AddCorsSetup();
//性能分析
//services.AddMiniProfilerSetup();
//HttpContext上下文
services.AddHttpContextSetup();
// 授权+认证 (jwt or ids4)
services.AddAuthorizationSetup();
if (Permissions.IsUseIds4) { services.AddAuthentication_Ids4Setup(); }
else { services.AddAuthentication_JWTSetup(); }
//IPLimit限流
services.AddIpPolicyRateLimitSetup(Configuration);
//筛选器
//services.AddScoped<UseServiceDIAttribute>();
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
// Default is true, make it false
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
//任务调度
services.AddJobSetup();
//添加PLC
services.AddPlcSetup();
//Redis缓存
//services.AddRedisCacheSetup();
//Redis队列
//services.AddRedisInitMqSetup();
//EventBus
//services.AddEventBusSetup();
//SignalR
//services.AddSignalR().AddNewtonsoftJsonProtocol();
//kestrel
//services.Configure<KestrelServerOptions>(x => x.AllowSynchronousIO = true)
// .Configure<IISServerOptions>(x => x.AllowSynchronousIO = true);
//Controller
services.AddControllers(o =>
{
// 全局异常过滤
o.Filters.Add(typeof(GlobalExceptionsFilter));
// 全局路由权限公约
//o.Conventions.Insert(0, new GlobalRouteAuthorizeConvention());
// 全局路由前缀,统一修改路由
o.Conventions.Insert(0, new GlobalRoutePrefixFilter(new RouteAttribute(RoutePrefix.Name)));
})
//全局配置Json序列化处理
.AddNewtonsoftJson(options =>
{
//忽略循环引用
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
//不使用驼峰样式的key
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
//忽略Model中为null的属性
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
// 设置时间格式
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
//设置本地时间而非UTC时间
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
});
services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
//支持编码大全 例如:支持 System.Text.Encoding.GetEncoding("GB2312") System.Text.Encoding.GetEncoding("GB18030")
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
}
//private X509Certificate2 GetCertificate()
//{
// var assembly = typeof(Startup).GetTypeInfo().Assembly;
// using (var stream = assembly.GetManifestResourceStream(
// assembly.GetManifestResourceNames().First(r => r.EndsWith("cnblogs.pfx"))))
// {
// if (stream == null)
// throw new ArgumentNullException(nameof(stream));
// var bytes = new byte[stream.Length];
// stream.Read(bytes, 0, bytes.Length);
// return new X509Certificate2(bytes);
// }
//}
/// <summary>
/// 注意在Program.CreateHostBuilder添加Autofac服务工厂
/// </summary>
/// <param name="builder"></param>
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterModule(new AutofacModuleRegister());
builder.RegisterModule<AutofacPropertityModuleReg>();
}
/// <summary>
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
/// </summary>
/// <param name="app"></param>
/// <param name="env"></param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ISysTasksQzService tasksQzService,
ISchedulerCenter schedulerCenter, IRunPlcService plc)
{
// Ip限流,尽量放管道外层
app.UseIpLimitMildd();
// 记录请求与返回数据
app.UseReuestResponseLog();
// 用户访问记录(必须放到外层,不然如果遇到异常,会报错,因为不能返回流)
app.UseRecordAccessLogsMildd();
// signalr
//app.UseSignalRSendMildd();
// 记录ip请求
app.UseIPLogMildd();
if (env.IsDevelopment())
{
// 在开发环境中,使用异常页面,这样可以暴露错误堆栈信息,所以不要放在生产环境。
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// 在非开发环境中使用HTTP严格安全传输(or HSTS) 对于保护web安全是非常重要的。
// 强制实施 HTTPS 在 ASP.NET Core配合 app.UseHttpsRedirection
//app.UseHsts();
}
// 封装Swagger展示
app.UseSwaggerMildd(() => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("Admin.Core.Api.index.html"));
// ↓↓↓↓↓↓ 注意下边这些中间件的顺序,很重要 ↓↓↓↓↓↓
// CORS跨域
app.UseCors(Appsettings.app(new string[] { "Startup", "Cors", "PolicyName" }));
// 跳转https
//app.UseHttpsRedirection();
// 使用静态文件,注意:如果开启需在对应目录创建文件夹,否则会报错
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "file")),
RequestPath = "/file",
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=600");
}
});
// 使用静态文件
app.UseStaticFiles();
app.UseSession();
//app.UseCookiePolicy();
// 返回错误码
app.UseStatusCodePages();
// Routing
app.UseRouting();
// 自定义授权中间件,可以尝试,但不推荐
// app.UseJwtTokenAuth();
// 先开启认证
app.UseAuthentication();
// 然后是授权中间件
app.UseAuthorization();
//开启性能分析
//app.UseMiniProfilerMildd();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
//使用集线器
//endpoints.MapHub<ChatHub>("/chatHub");
//GlobalHost.Configuration.MaxIncomingWebSocketMessageSize = null;
});
// 开启QuartzNetJob调度服务
app.UseQuartzJobMildd(tasksQzService, schedulerCenter);
//PLC
app.UsePlcMildd(plc);
// 服务注册
//app.UseConsulMildd(Configuration, lifetime);
// 事件总线,订阅服务
//app.ConfigureEventBus();
}
}
}