EasyMES/WaterCloud.Web/Startup.cs
2022-11-03 15:11:15 +08:00

322 lines
14 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 CSRedis;
using System.IO;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using WaterCloud.Code;
using WaterCloud.Code.Model;
using System.Text.Encodings.Web;
using System.Text.Unicode;
using Newtonsoft.Json.Serialization;
using WaterCloud.Service.AutoJob;
using WaterCloud.DataBase;
using System.Reflection;
using System.Linq;
using WaterCloud.Service;
using Autofac;
using Microsoft.AspNetCore.Mvc;
using Quartz;
using Quartz.Impl;
using Quartz.Spi;
using System;
using Chloe.Infrastructure.Interception;
using Microsoft.Extensions.FileProviders;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.ResponseCompression;
using System.IO.Compression;
using WaterCloud.Domain.SystemOrganize;
using Microsoft.OpenApi.Models;
using System.Collections.Generic;
namespace WaterCloud.Web
{
public class Startup
{
public IConfiguration Configuration { get; }
public IWebHostEnvironment WebHostEnvironment { get; set; }
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
Configuration = configuration;
WebHostEnvironment = env;
GlobalContext.LogWhenStart(env);
GlobalContext.HostingEnvironment = env;
}
// This method gets called by the runtime. Use this method to add services to the container.
public async void ConfigureServices(IServiceCollection services)
{
GlobalContext.SystemConfig = Configuration.GetSection("SystemConfig").Get<SystemConfig>();
GlobalContext.Services = services;
GlobalContext.Configuration = Configuration;
services.AddSwaggerGen(config =>
{
config.SwaggerDoc("v1", new OpenApiInfo { Title = "WaterCloud Api", Version = "v1" });
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
config.IncludeXmlComments(xmlPath, true); //添加控制器层注释true表示显示控制器注释
config.AddSecurityDefinition(GlobalContext.SystemConfig.TokenName, new OpenApiSecurityScheme
{
Description = "header token",
Name = GlobalContext.SystemConfig.TokenName,
In = ParameterLocation.Header,
Scheme = "",
Type = SecuritySchemeType.ApiKey,//设置类型
BearerFormat = ""
});
config.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = GlobalContext.SystemConfig.TokenName }
},
new List<string>()
}
});
});
services.AddSession();
//代替HttpContext.Current
services.AddHttpContextAccessor();
//缓存缓存选择
if (Configuration.GetSection("SystemConfig:CacheProvider").Value!= Define.CACHEPROVIDER_REDIS)
{
services.AddMemoryCache();
}
else
{
//redis 注入服务
string redisConnectiong = Configuration.GetSection("SystemConfig:RedisConnectionString").Value;
// 多客户端 1、基础 2、操作日志
var redisDB1 = new CSRedisClient(redisConnectiong + ",defaultDatabase=" + 0);
BaseHelper.Initialization(redisDB1);
var redisDB2 = new CSRedisClient(redisConnectiong + ",defaultDatabase=" + 1);
HandleLogHelper.Initialization(redisDB2);
services.AddSingleton(redisDB1);
services.AddSingleton(redisDB2);
}
//连续guid初始化,示例IDGenerator.NextId()
services.AddSingleton<IDistributedIDGenerator, SequentialGuidIDGenerator>();
#region
//注入数据库连接
services.AddScoped<Chloe.IDbContext>((serviceProvider) =>
{
return DBContexHelper.Contex();
});
#region Quartz调度类
services.AddSingleton<JobExecute>();
//注册ISchedulerFactory的实例。
services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
services.AddSingleton<IJobFactory, IOCJobFactory>();
//是否开启后台任务
if (Configuration.GetSection("SystemConfig:OpenQuarz").Value == "True")
{
services.AddHostedService<JobCenter>();
}
#endregion
//注入SignalR实时通讯默认用json传输
services.AddSignalR(options =>
{
//客户端发保持连接请求到服务端最长间隔默认30秒改成4分钟网页需跟着设置connection.keepAliveIntervalInMilliseconds = 12e4;即2分钟
options.ClientTimeoutInterval = TimeSpan.FromMinutes(4);
//服务端发保持连接请求到客户端间隔默认15秒改成2分钟网页需跟着设置connection.serverTimeoutInMilliseconds = 24e4;即4分钟
options.KeepAliveInterval = TimeSpan.FromMinutes(2);
});
////注册html解析
//services.AddSingleton(HtmlEncoder.Create(UnicodeRanges.All));
////注册特性
//services.AddScoped<HandlerLoginAttribute>();
//services.AddScoped<HandlerAuthorizeAttribute>();
////ajax不能使用注入
////services.AddScoped<HandlerAjaxOnlyAttribute>();
//services.AddScoped<HandlerAdminAttribute>();
#endregion
services.AddCors(options => options.AddPolicy("CorsPolicy",
builder =>
{
builder.AllowAnyMethod().AllowAnyHeader()
.WithOrigins(Configuration.GetSection("SystemConfig:AllowCorsSite").Value.Split(","))
.AllowCredentials();
}));
services.AddHttpClient();
services.AddControllersWithViews(options =>
{
options.Filters.Add<GlobalExceptionFilter>();
options.Filters.Add<ModelActionFilter>();
options.ModelMetadataDetailsProviders.Add(new ModelBindingMetadataProvider());
//options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
}).AddNewtonsoftJson(options =>
{
// 返回数据首字母不小写CamelCasePropertyNamesContractResolver是小写
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
}).AddControllersAsServices().AddRazorRuntimeCompilation();
services.AddDirectoryBrowser();
services.AddControllers(options =>
{
options.Filters.Add<ModelActionFilter>();
options.ModelMetadataDetailsProviders.Add(new ModelBindingMetadataProvider());
}).ConfigureApiBehaviorOptions(options =>
{
options.SuppressModelStateInvalidFilter = true;
});
services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN");
//启用 Gzip 和 Brotil 压缩功能
services.AddResponseCompression(options =>
{
options.Providers.Add<BrotliCompressionProvider>();
options.Providers.Add<GzipCompressionProvider>();
options.MimeTypes =
ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "image/svg+xml" });
});
services.Configure<BrotliCompressionProviderOptions>(options =>
{
options.Level = (CompressionLevel)4; // 4 or 5 is OK
});
services.AddOptions();
services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(GlobalContext.HostingEnvironment.ContentRootPath + Path.DirectorySeparatorChar + "DataProtection"));
//更新数据库管理员和主系统
try
{
if (GlobalContext.SystemConfig.ReviseSysem == true)
{
using (var context = DBContexHelper.Contex())
{
var setentity = context.Query<SystemSetEntity>().FirstOrDefault();
context.Session.BeginTransaction();
var user = context.Query<UserEntity>().Where(a => a.F_Account == setentity.F_AdminAccount).FirstOrDefault();
var userinfo = context.Query<UserLogOnEntity>().Where(a => a.F_UserId == user.F_Id).FirstOrDefault();
userinfo.F_UserSecretkey = Md5.md5(Utils.CreateNo(), 16).ToLower();
userinfo.F_UserPassword = Md5.md5(DESEncrypt.Encrypt(Md5.md5(GlobalContext.SystemConfig.SysemUserPwd, 32).ToLower(), userinfo.F_UserSecretkey).ToLower(), 32).ToLower();
context.Update<UserEntity>(a => a.F_Id == user.F_Id, a => new UserEntity
{
F_Account = GlobalContext.SystemConfig.SysemUserCode
});
var cacheKeyUser = "watercloud_userdata_";
await CacheHelper.Remove(cacheKeyUser + user.F_Id);
await context.UpdateAsync<UserLogOnEntity>(a => a.F_Id == userinfo.F_Id, a => new UserLogOnEntity
{
F_UserPassword = userinfo.F_UserPassword,
F_UserSecretkey = userinfo.F_UserSecretkey
});
await context.UpdateAsync<SystemSetEntity>(a => a.F_Id == userinfo.F_Id, a => new SystemSetEntity
{
F_AdminAccount = GlobalContext.SystemConfig.SysemUserCode,
F_AdminPassword = GlobalContext.SystemConfig.SysemUserPwd
});
context.Session.CommitTransaction();
var cacheKeyOperator = "watercloud_operator_";// +登录者token
await CacheHelper.Remove(cacheKeyOperator + "info_" + user.F_Id);
}
}
}
catch (Exception ex)
{
LogHelper.Write(ex);
}
//清理缓存
//CacheHelper.FlushAll().GetAwaiter().GetResult();
}
//AutoFac注入
public void ConfigureContainer(ContainerBuilder builder)
{
var assemblys = Assembly.Load("WaterCloud.Service");//Service是继承接口的实现方法类库名称
            var baseType = typeof(IDenpendency);//IDenpendency 是一个接口(所有要实现依赖注入的借口都要继承该接口)
            builder.RegisterAssemblyTypes(assemblys).Where(m => baseType.IsAssignableFrom(m) && m != baseType)
.InstancePerLifetimeScope()//生命周期,这里没有使用接口方式
.PropertiesAutowired() ;//属性注入
//Controller中使用属性注入
var controllerBaseType = typeof(Controller);
builder.RegisterAssemblyTypes(typeof(Program).Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired();
//注册html解析
builder.RegisterInstance(HtmlEncoder.Create(UnicodeRanges.All)).SingleInstance();
//注册特性
builder.RegisterType(typeof(HandlerLoginAttribute)).InstancePerLifetimeScope();
builder.RegisterType(typeof(HandlerAuthorizeAttribute)).InstancePerLifetimeScope();
builder.RegisterType(typeof(HandlerAdminAttribute)).InstancePerLifetimeScope();
builder.RegisterType(typeof(HandlerLockAttribute)).InstancePerLifetimeScope();
//ControllerBase中使用属性注入
controllerBaseType = typeof(ControllerBase);
builder.RegisterAssemblyTypes(typeof(Program).Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired();
//注册特性
builder.RegisterType(typeof(AuthorizeFilterAttribute)).InstancePerLifetimeScope();
builder.RegisterType(typeof(LoginFilterAttribute)).InstancePerLifetimeScope();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app)
{
//由于.Net Core默认只会从wwwroot目录加载静态文件其他文件夹的静态文件无法正常访问。
//而我们希望将图片上传到网站根目录的upload文件夹下所以需要额外在Startup.cs类的Configure方法中
string resource = Path.Combine(Directory.GetCurrentDirectory(), "upload");
if (!FileHelper.IsExistDirectory(resource))
{
FileHelper.CreateFolder(resource);
}
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(resource),
RequestPath = "/upload",
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=36000");
}
});
app.UseCors("CorsPolicy");
if (WebHostEnvironment.IsDevelopment())
{
//打印sql
IDbCommandInterceptor interceptor = new DbCommandInterceptor();
DbInterception.Add(interceptor);
GlobalContext.SystemConfig.Debug = true;
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error?msg=404");
}
//文件地址Resource
//静态资源wwwroot
app.UseStaticFiles(new StaticFileOptions
{
ContentTypeProvider = new CustomerFileExtensionContentTypeProvider(),
OnPrepareResponse = GlobalContext.SetCacheControl
});
//启用 Gzip 和 Brotil 压缩功能
app.UseResponseCompression();
app.Use(next => context =>
{
context.Request.EnableBuffering();
return next(context);
});
app.UseSwagger(c =>
{
c.RouteTemplate = "api-doc/{documentName}/swagger.json";
});
app.UseSwaggerUI(c =>
{
c.RoutePrefix = "api-doc";
c.SwaggerEndpoint("v1/swagger.json", "WaterCloud Api v1");
});
//session
app.UseSession();
//路径
app.UseRouting();
//MVC路由
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<MessageHub>("/chatHub");
endpoints.MapControllerRoute("areas", "{area:exists}/{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute("default", "{controller=Login}/{action=Index}/{id?}");
endpoints.MapControllerRoute("api", "api/{controller=ApiHome}/{action=Index}/{id?}");
});
GlobalContext.ServiceProvider = app.ApplicationServices;
}
}
}