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.
CoreShop/CoreCms.Net.Web.WebApi/Startup.cs

350 lines
12 KiB
C#

using Autofac;
using AutoMapper;
using CoreCms.Net.Auth;
using CoreCms.Net.Configuration;
using CoreCms.Net.Core.AutoFac;
using CoreCms.Net.Core.Config;
using CoreCms.Net.Filter;
using CoreCms.Net.Loging;
using CoreCms.Net.Mapping;
using CoreCms.Net.Middlewares;
using CoreCms.Net.Model.ViewModels.Options;
using CoreCms.Net.Model.ViewModels.Sms;
using CoreCms.Net.Services.Mediator;
using CoreCms.Net.Swagger;
using CoreCms.Net.Task;
using Essensoft.AspNetCore.Payment.Alipay;
using Essensoft.AspNetCore.Payment.WeChatPay;
using Hangfire;
using Hangfire.Dashboard.BasicAuthorization;
using InitQ;
using MediatR;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Localization;
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.Hosting;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Qc.YilianyunSdk;
using Senparc.CO2NET;
using Senparc.CO2NET.AspNet;
using Senparc.Weixin;
using Senparc.Weixin.Entities;
using Senparc.Weixin.RegisterServices;
using Senparc.Weixin.WxOpen;
using System;
using System.Collections.Generic;
using System.Linq;
using CoreCms.Net.RedisMQ.Subscribe;
using CoreCms.Net.Utility.Extensions;
namespace CoreCms.Net.Web.WebApi
{
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public class Startup
{
/// <summary>
/// <20><><EFBFBD><EFBFBD><ECBAAF>
/// </summary>
/// <param name="configuration"></param>
/// <param name="env"></param>
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
Configuration = configuration;
Env = env;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public IConfiguration Configuration { get; }
/// <summary>
/// web<65><62><EFBFBD><EFBFBD>
/// </summary>
public IWebHostEnvironment Env { get; }
/// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//<2F><><EFBFBD>ӱ<EFBFBD><D3B1><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD>ȡ֧<C8A1><D6A7>
services.AddSingleton(new AppSettingsHelper(Env.ContentRootPath));
services.AddSingleton(new LogLockHelper(Env.ContentRootPath));
//Memory<72><79><EFBFBD><EFBFBD>
services.AddMemoryCacheSetup();
//Redis<69><73><EFBFBD><EFBFBD>
services.AddRedisCacheSetup();
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD><EFBFBD><EFBFBD>SqlSugarע<72><D7A2>֧<EFBFBD><D6A7>
services.AddSqlSugarSetup();
//<2F><><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD>CORS<52><53>
services.AddCorsSetup();
//<2F><><EFBFBD><EFBFBD>session֧<6E><D6A7>(session<6F><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD>cache<68><65><EFBFBD>д洢)
services.AddSession();
// AutoMapper֧<72><D6A7>
services.AddAutoMapper(typeof(AutoMapperConfiguration));
//MediatR
services.AddMediatR(typeof(OrderPayedCommand).Assembly);
//ʹ<><CAB9> SignalR
services.AddSignalR();
//Redis<69><73>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>
services.AddRedisMessageQueueSetup();
// <20><><EFBFBD><EFBFBD>Payment <20><><EFBFBD><EFBFBD>ע<EFBFBD><D7A2><><D6A7><EFBFBD><EFBFBD>֧<EFBFBD><D6A7><><CEA2>֧<EFBFBD><D6A7>)
services.AddAlipay();
services.AddWeChatPay();
// <20><> appsettings.json <20><> <20><><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>
services.Configure<WeChatPayOptions>(Configuration.GetSection("WeChatPay"));
services.Configure<AlipayOptions>(Configuration.GetSection("Alipay"));
//Swagger<65>ӿ<EFBFBD><D3BF>ĵ<EFBFBD>ע<EFBFBD><D7A2>
services.AddClientSwaggerSetup();
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƴ<EFBFBD>ӡ<EFBFBD><D3A1>
services.AddYiLianYunSetup();
//<2F><>Ȩ֧<C8A8><D6A7>ע<EFBFBD><D7A2>
services.AddAuthorizationSetupForClient();
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><D7A2>
services.AddHttpContextSetup();
//΢<><CEA2>ע<EFBFBD><D7A2>
services.AddSenparcWeixinServices(Configuration);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><D0BC><EFBFBD>AutoFac<61><63><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6BBBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
//ע<><D7A2>mvc<76><63>ע<EFBFBD><D7A2>razor<6F><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
services.AddMvc(options =>
{
//ʵ<><CAB5><EFBFBD><EFBFBD>֤
options.Filters.Add<RequiredErrorForClent>();
//<2F><EFBFBD><ECB3A3><EFBFBD><EFBFBD>
options.Filters.Add<GlobalExceptionsFilterForClent>();
//Swagger<65>޳<EFBFBD><DEB3><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>apiչʾ<D5B9><CABE><EFBFBD>б<EFBFBD>
options.Conventions.Add(new ApiExplorerIgnores());
})
.AddNewtonsoftJson(p =>
{
//<2F><><EFBFBD>ݸ<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>ĸСд <20><>ʹ<EFBFBD><CAB9><EFBFBD>շ<EFBFBD>
p.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
//<2F><>ʹ<EFBFBD><CAB9><EFBFBD>շ<EFBFBD><D5B7><EFBFBD>ʽ<EFBFBD><CABD>key
//p.SerializerSettings.ContractResolver = new DefaultContractResolver();
//<2F><><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
p.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
//<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>yyyy/MM/dd<64><64>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>Ϊiosϵͳ<CFB5><CDB3>֧<EFBFBD><D6A7>2018-03-29<32><39>ʽ<EFBFBD><CABD>ʱ<EFBFBD>䣬ֻʶ<D6BB><CAB6>2018/03/09<30><39><EFBFBD>ָ<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>
p.SerializerSettings.DateFormatString = "yyyy/MM/dd HH:mm:ss";
});
}
/// <summary>
/// Autofac<61><63><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="builder"></param>
public void ConfigureContainer(ContainerBuilder builder)
{
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD>п<EFBFBD><D0BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><D7A2>
var controllerBaseType = typeof(ControllerBase);
builder.RegisterAssemblyTypes(typeof(Program).Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired();
builder.RegisterModule(new AutofacModuleRegister());
}
// public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IOptions<SenparcSetting> senparcSetting, IOptions<SenparcWeixinSetting> senparcWeixinSetting)
/// <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>
/// <param name="senparcSetting"></param>
/// <param name="senparcWeixinSetting"></param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IOptions<SenparcSetting> senparcSetting,
IOptions<SenparcWeixinSetting> senparcWeixinSetting)
{
// <20><>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBB7B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><EFBFBD><E2BFAA>Ȩ<EFBFBD>ޣ<EFBFBD><DEA3><EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD>д<EFBFBD><D0B4>)
app.UseReuestResponseLog();
// <20>û<EFBFBD><C3BB><EFBFBD><EFBFBD>ʼ<EFBFBD>¼(<28><><EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD><C5B5><EFBFBD><EFBFBD><EFBFBD><E3A3AC>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><ECB3A3><EFBFBD><EFBFBD><E1B1A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD><EFBFBD><EFBFBD>)(ע<><EFBFBD><E2BFAA>Ȩ<EFBFBD>ޣ<EFBFBD><DEA3><EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD>д<EFBFBD><D0B4>)
app.UseRecordAccessLogsMildd();
// <20><>¼ip<69><70><EFBFBD><EFBFBD><><EFBFBD><E2BFAA>Ȩ<EFBFBD>ޣ<EFBFBD><DEA3><EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD>д<EFBFBD><D0B4>)
app.UseIpLogMildd();
//ǿ<><C7BF><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-CN");
app.UseSwagger().UseSwaggerUI(c =>
{
//<2F><><EFBFBD>ݰ汾<DDB0><E6B1BE><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD> <20><><EFBFBD><EFBFBD>չʾ
typeof(CustomApiVersion.ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach(
version =>
{
c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"Doc {version}");
});
//<2F><><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>swagger-ui
c.RoutePrefix = "doc";
//c.RoutePrefix = string.Empty;
});
#region Hangfire<72><65>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
var queues = new string[] { GlobalEnumVars.HangFireQueuesConfig.@default.ToString(), GlobalEnumVars.HangFireQueuesConfig.apis.ToString(), GlobalEnumVars.HangFireQueuesConfig.web.ToString(), GlobalEnumVars.HangFireQueuesConfig.recurring.ToString() };
app.UseHangfireServer(new BackgroundJobServerOptions
{
ServerTimeout = TimeSpan.FromMinutes(4),
SchedulePollingInterval = TimeSpan.FromSeconds(15),//<2F><EFBFBD><EBBCB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>ö̵㣬һ<E3A3AC><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC>ʱ<EFBFBD>䣬Ĭ<E4A3AC><C4AC>15<31><35>
ShutdownTimeout = TimeSpan.FromMinutes(30),//<2F><>ʱʱ<CAB1><CAB1>
Queues = queues,//<2F><><EFBFBD><EFBFBD>
WorkerCount = Math.Max(Environment.ProcessorCount, 20)//<2F><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̣߳<DFB3>Ĭ<EFBFBD><C4AC>20
});
//<2F><>Ȩ
var filter = new BasicAuthAuthorizationFilter(
new BasicAuthAuthorizationFilterOptions
{
SslRedirect = false,
// Require secure connection for dashboard
RequireSsl = false,
// Case sensitive login checking
LoginCaseSensitive = false,
// Users
Users = new[]
{
new BasicAuthAuthorizationUser
{
Login = AppSettingsConstVars.HangFireLogin,
PasswordClear = AppSettingsConstVars.HangFirePassWord
}
}
});
var options = new DashboardOptions
{
AppPath = "/",//<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ת<EFBFBD>ĵ<EFBFBD>ַ
DisplayStorageConnectionString = false,//<2F>Ƿ<EFBFBD><C7B7><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
Authorization = new[]
{
filter
},
IsReadOnlyFunc = Context =>
{
return false;//<2F>Ƿ<EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
};
app.UseHangfireDashboard("/job", options); //<2F><><EFBFBD>Ըı<D4B8>Dashboard<72><64>url
HangfireDispose.HangfireService();
#endregion
#region ʢ<><CAA2>΢<EFBFBD><CEA2>ע<EFBFBD><D7A2>
// <20><><EFBFBD><EFBFBD> CO2NET ȫ<><C8AB>ע<EFBFBD><EFBFBD><E1A3AC><EFBFBD>
var registerService = app.UseSenparcGlobal(env, senparcSetting.Value, globalRegister =>
{
#region CO2NET ȫ<><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#endregion
}, true)
//ʹ<><CAB9> Senparc.Weixin SDK
.UseSenparcWeixin(senparcWeixinSetting.Value, weixinRegister =>
{
#region ΢<><CEA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/* ΢<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD>ʼ
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>һλ<EFBFBD><EFBFBD>
*/
#region ע<><EFBFBD>ںŻ<DABA>С<EFBFBD><D0A1><EFBFBD>򣨰<EFBFBD><F2A3A8B0>
weixinRegister
//ע<><EFBFBD>ں<EFBFBD>
//.RegisterMpAccount(senparcWeixinSetting.Value, "<22><><EFBFBD>ں<EFBFBD>")
//ע<><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ںŻ<DABA>С<EFBFBD><D0A1><EFBFBD><EFBFBD>
.RegisterWxOpenAccount(senparcWeixinSetting.Value, "С<><D0A1><EFBFBD><EFBFBD>")
//AccessTokenContainer.Register(appId, appSecret, name);//<2F><><EFBFBD><EFBFBD><EFBFBD>ռ䣺Senparc.Weixin.MP.Containers
#endregion
;
/* ΢<><CEA2><EFBFBD><EFBFBD><EFBFBD>ý<EFBFBD><C3BD><EFBFBD> */
#endregion
});
#endregion
//ʹ<><CAB9> Session
app.UseSession();
if (env.IsDevelopment())
{
// <20>ڿ<EFBFBD><DABF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD>쳣ҳ<ECB3A3><EFBFBD><E6A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ա<EFBFBD><EFBFBD><C2B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD>Բ<EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
// CORS<52><53><EFBFBD><EFBFBD>
app.UseCors(AppSettingsConstVars.CorsPolicyName);
// Routing
app.UseRouting();
// ʹ<>þ<EFBFBD>̬<EFBFBD>ļ<EFBFBD>
app.UseStaticFiles();
// <20>ȿ<EFBFBD><C8BF><EFBFBD><EFBFBD><EFBFBD>֤
app.UseAuthentication();
// Ȼ<><C8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD>м<EFBFBD><D0BC><EFBFBD>
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
"areas",
"{area:exists}/{controller=Default}/{action=Index}/{id?}"
);
//endpoints.MapControllers();
endpoints.MapControllerRoute(
"default",
"{controller=Default}/{action=Index}/{id?}");
});
//<2F><><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD>ʼҳ<CABC><D2B3><EFBFBD><EFBFBD>default.html<6D><6C>
//<2F>˴<EFBFBD><CBB4><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>wwwroot<6F>ļ<EFBFBD><C4BC>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7>
var defaultFilesOptions = new DefaultFilesOptions();
defaultFilesOptions.DefaultFileNames.Clear();
defaultFilesOptions.DefaultFileNames.Add("index.html");
app.UseDefaultFiles(defaultFilesOptions);
app.UseStaticFiles();
}
}
}