diff --git a/CoreCms.Net.Configuration/AppSettingsHelper.cs b/CoreCms.Net.Configuration/AppSettingsHelper.cs index 9c893aa..b88f9e5 100644 --- a/CoreCms.Net.Configuration/AppSettingsHelper.cs +++ b/CoreCms.Net.Configuration/AppSettingsHelper.cs @@ -1,4 +1,4 @@ - + using System; using System.Linq; using System.Net.NetworkInformation; @@ -13,7 +13,7 @@ using SqlSugar.Extensions; namespace CoreCms.Net.Configuration { /// - /// »ñÈ¡AppsettingsÅäÖÃÐÅÏ¢ + /// 获å�–Appsettingsé…�置信æ�¯ /// public class AppSettingsHelper { @@ -25,7 +25,7 @@ namespace CoreCms.Net.Configuration .SetBasePath(contentPath) .Add(new JsonConfigurationSource { Path = "appsettings.json", Optional = false, ReloadOnChange = true }); - //·Ç Production »·¾³×·¼Ó¼ÓÔØ¶ÔÓ¦µÄ»·¾³ÅäÖÃÎļþ£¨Èç appsettings.Development.json£©£¬ÓÃÓÚ±¾µØ¸²¸ÇĬÈÏÅäÖà + //é�ž Production 环境追加加载对应的环境é…�置文件(如 appsettings.Development.json),用于本地覆盖默认é…�ç½® if (!string.IsNullOrEmpty(environmentName) && !environmentName.Equals("Production", StringComparison.OrdinalIgnoreCase)) { @@ -41,10 +41,10 @@ namespace CoreCms.Net.Configuration } /// - /// ·â×°Òª²Ù×÷µÄ×Ö·û + /// å°�装è¦�æ“�作的字符 /// AppSettingsHelper.GetContent(new string[] { "JwtConfig", "SecretKey" }); /// - /// ½ÚµãÅäÖà + /// 节点é…�ç½® /// public static string GetContent(params string[] sections) { @@ -65,20 +65,20 @@ namespace CoreCms.Net.Configuration /// - /// »ñÈ¡µçÄÔ MAC£¨ÎïÀí£© µØÖ· + /// 获å�–电脑 MAC(物ç�†ï¼‰ 地å�€ /// - /// ÊÇ·ñÖ»ÊÇΪÁËÌ×È¡keyÉú³ÉÒ»¸ö²»Í¬²¿Êð»·¾³²»Í¬µÄÐòÁд® + /// 是å�¦å�ªæ˜¯ä¸ºäº†å¥—å�–key生æˆ�一个ä¸�å�Œéƒ¨ç½²çŽ¯å¢ƒä¸�å�Œçš„åº�列串 /// public static string GetMACIp(bool needToken) { - //±¾µØ¼ÆËã»úÍøÂçÁ¬½ÓÐÅÏ¢ + //本地计算机网络连接信æ�¯ IPGlobalProperties computerProperties = IPGlobalProperties.GetIPGlobalProperties(); - //»ñÈ¡±¾»úËùÓÐÍøÂçÁ¬½Ó + //获å�–本机所有网络连接 NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces(); - //»ñÈ¡±¾»úµçÄÔÃû + //获å�–本机电脑å�� var HostName = computerProperties.HostName; - //»ñÈ¡ÓòÃû + //获å�–域å�� var DomainName = computerProperties.DomainName; if (nics == null || nics.Length < 1) @@ -93,7 +93,7 @@ namespace CoreCms.Net.Configuration var adapterDescription = adapter.Description; var NetworkInterfaceType = adapter.NetworkInterfaceType; - if (adapterName == "±¾µØÁ¬½Ó" || needToken) + if (adapterName == "本地连接" || needToken) { PhysicalAddress address = adapter.GetPhysicalAddress(); byte[] bytes = address.GetAddressBytes(); @@ -114,15 +114,15 @@ namespace CoreCms.Net.Configuration } /// - /// »ñÈ¡µçÄÔ¼ÆËã»úÃû + /// 获å�–电脑计算机å�� /// /// public static string GetHostName() { - //±¾µØ¼ÆËã»úÍøÂçÁ¬½ÓÐÅÏ¢ + //本地计算机网络连接信æ�¯ IPGlobalProperties computerProperties = IPGlobalProperties.GetIPGlobalProperties(); - //»ñÈ¡±¾»úµçÄÔÃû + //获å�–本机电脑å�� var hostName = computerProperties.HostName; return !string.IsNullOrEmpty(hostName) ? hostName : "CoreShop.Professional"; @@ -133,25 +133,25 @@ namespace CoreCms.Net.Configuration /// - /// תMD5 + /// 转MD5 /// /// /// public static string GetMachineRandomKey(string str) { MD5 md5 = MD5.Create(); - // ½«×Ö·û´®×ª»»³É×Ö½ÚÊý×é + // 将字符串转æ�¢æˆ�字节数组 byte[] byteOld = Encoding.UTF8.GetBytes(str); - // µ÷ÓüÓÃÜ·½·¨ + // 调用加密方法 byte[] byteNew = md5.ComputeHash(byteOld); - // ½«¼ÓÃܽá¹ûת»»Îª×Ö·û´® + // 将加密结果转æ�¢ä¸ºå­—符串 StringBuilder sb = new StringBuilder(); foreach (byte b in byteNew) { - // ½«×Ö½Úת»»³É16½øÖƱíʾµÄ×Ö·û´®£¬ + // 将字节转æ�¢æˆ�16进制表示的字符串, sb.Append(b.ToString("x2")); } - // ·µ»Ø¼ÓÃܵÄ×Ö·û´® + // 返回加密的字符串 return sb.ToString(); } diff --git a/CoreCms.Net.Web.Admin/Program.cs b/CoreCms.Net.Web.Admin/Program.cs index 374fa30..fee8b87 100644 --- a/CoreCms.Net.Web.Admin/Program.cs +++ b/CoreCms.Net.Web.Admin/Program.cs @@ -1,4 +1,4 @@ -using Autofac.Extensions.DependencyInjection; +using Autofac.Extensions.DependencyInjection; using CoreCms.Net.Loging; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; @@ -32,96 +32,96 @@ using Yitter.IdGenerator; var builder = WebApplication.CreateBuilder(args); -//Ìí¼Ó±¾µØÂ·¾¶»ñȡ֧³Ö +//添加本地路径获å�–支æŒ� builder.Services.AddSingleton(new AppSettingsHelper(builder.Environment.ContentRootPath, builder.Environment.EnvironmentName)); builder.Services.AddSingleton(new LogLockHelper(builder.Environment.ContentRootPath)); -//Memory»º´æ +//Memory缓存 builder.Services.AddMemoryCacheSetup(); -//Redis»º´æ +//Redis缓存 builder.Services.AddRedisCacheSetup(); -//Ìí¼ÓÊý¾Ý¿âÁ¬½ÓSqlSugar×¢ÈëÖ§³Ö +//添加数æ�®åº“连接SqlSugar注入支æŒ� builder.Services.AddSqlSugarSetup(); -//ÅäÖÿçÓò£¨CORS£© +//é…�置跨域(CORS) builder.Services.AddCorsSetup(); -//Ìí¼ÓsessionÖ§³Ö(sessionÒÀÀµÓÚcache½øÐд洢) +//添加session支æŒ�(sessionä¾�赖于cache进行存储) builder.Services.AddSession(); -// AutoMapperÖ§³Ö -// AutoMapperÖ§³Ö£¨15°æ±¾ºóÆôÓÃÁËÊÚȨģʽ£¬´ó¼Ò¿ÉÒÔǰÍùhttps://luckypennysoftware.com/ÉêÇë×Ô¼ºÃâ·ÑµÄkey£© +// AutoMapper支æŒ� +// AutoMapper支æŒ�(15版本å�Žå�¯ç”¨äº†æŽˆæ�ƒæ¨¡å¼�,大家å�¯ä»¥å‰�å¾€https://luckypennysoftware.com/申请自己å…�费的key) //builder.Services.AddAutoMapper(typeof(AutoMapperConfiguration)); builder.Services.AddAutoMapper(cfg => cfg.LicenseKey = AppSettingsConstVars.AutoMapperLicenseKey, typeof(AutoMapperConfiguration)); -//ʹÓà SignalR +//使用 SignalR builder.Services.AddSignalR(); -// ÒýÈëPayment ÒÀÀµ×¢Èë(Ö§¸¶±¦Ö§¸¶/΢ÐÅÖ§¸¶) +// 引入Payment ä¾�赖注入(支付å®�支付/微信支付) builder.Services.AddAlipay(); builder.Services.AddWeChatPay(); -// ÔÚ appsettings.json ÖÐ ÅäÖÃÑ¡Ïî +// 在 appsettings.json 中 é…�置选项 builder.Services.Configure(builder.Configuration.GetSection("WeChatPay")); builder.Services.Configure(builder.Configuration.GetSection("Alipay")); -//×¢²á×Ô¶¨Òå΢ÐŽӿÚÅäÖÃÎļþ +//注册自定义微信接å�£é…�置文件 builder.Services.Configure(builder.Configuration.GetSection(nameof(CoreCms.Net.WeChat.Service.Options.WeChatOptions))); -// ×¢È빤³§ HTTP ¿Í»§¶Ë +// 注入工厂 HTTP 客户端 builder.Services.AddHttpClient(); builder.Services.AddSingleton(); -//Swagger½Ó¿ÚÎĵµ×¢Èë +//Swagger接å�£æ–‡æ¡£æ³¨å…¥ builder.Services.AddAdminSwaggerSetup(); -//ÅäÖÃÒ×ÁªÔÆ´òÓ¡»ú +//é…�置易è�”云打å�°æœº builder.Services.AddYiLianYunSetup(); -//jwtÊÚȨ֧³Ö×¢Èë +//jwt授æ�ƒæ”¯æŒ�注入 builder.Services.AddAuthorizationSetupForAdmin(); -//ÉÏÏÂÎÄ×¢Èë +//上下文注入 builder.Services.AddHttpContextSetup(); -//·þÎñÅäÖÃÖмÓÈëAutoFac¿ØÖÆÆ÷Ìæ»»¹æÔò¡£ +//æœ�务é…�置中加入AutoFac控制器替æ�¢è§„则。 builder.Services.Replace(ServiceDescriptor.Transient()); -//×¢²ámvc£¬×¢²árazorÒýÇæÊÓͼ +//注册mvc,注册razor引擎视图 builder.Services.AddMvc(options => { - //ʵÌåÑéÖ¤ + //实体验è¯� options.Filters.Add(); - //Òì³£´¦Àí + //异常处ç�† options.Filters.Add(); - //SwaggerÌÞ³ý²»ÐèÒª¼ÓÈëapiչʾµÄÁбí + //Swagger剔除ä¸�需è¦�加入api展示的列表 options.Conventions.Add(new ApiExplorerIgnores()); options.EnableEndpointRouting = false; }) .AddNewtonsoftJson(p => { - //Êý¾Ý¸ñʽÊ××ÖĸСд ²»Ê¹ÓÃÍÕ·å + //æ•°æ�®æ ¼å¼�首字æ¯�å°�写 ä¸�使用驼峰 p.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); - //²»Ê¹ÓÃÍÕ·åÑùʽµÄkey + //ä¸�使用驼峰样å¼�çš„key //p.SerializerSettings.ContractResolver = new DefaultContractResolver(); - //ºöÂÔÑ­»·ÒýÓà + //忽略循环引用 p.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; - //ÉèÖÃʱ¼ä¸ñʽ + //设置时间格å¼� p.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; }); -// Ñ©»¨Æ¯ÒÆËã·¨ -// ´´½¨ IdGeneratorOptions ¶ÔÏó£¬ÇëÔÚ¹¹Ô캯ÊýÖÐÊäÈë WorkerId£º +// 雪花漂移算法 +// 创建 IdGeneratorOptions 对象,请在构造函数中输入 WorkerId: var options = new IdGeneratorOptions(AppSettingsConstVars.SnowflakeIdWorkerId); -// ±£´æ²ÎÊý£¨±ØÐëµÄ²Ù×÷£¬·ñÔòÒÔÉÏÉèÖö¼²»ÄÜÉúЧ£©£º +// ä¿�å­˜å�‚数(必须的æ“�作,å�¦åˆ™ä»¥ä¸Šè®¾ç½®éƒ½ä¸�能生效): YitIdHelper.SetIdGenerator(options); -#region AutoFac×¢²á============================================================================ +#region AutoFac注册============================================================================ builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); builder.Host.ConfigureContainer(containerBuilder => { - //»ñÈ¡ËùÓпØÖÆÆ÷ÀàÐͲ¢Ê¹ÓÃÊôÐÔ×¢Èë + //获å�–所有控制器类型并使用属性注入 var controllerBaseType = typeof(ControllerBase); containerBuilder.RegisterAssemblyTypes(typeof(Program).Assembly) .Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType) @@ -135,23 +135,23 @@ builder.Host.ConfigureContainer(containerBuilder => var app = builder.Build(); -#region ½â¾öUbuntu Nginx ´úÀí²»ÄÜ»ñÈ¡IPÎÊÌâ +#region 解决Ubuntu Nginx 代ç�†ä¸�能获å�–IP问题 app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); #endregion -// ¼Ç¼ÇëÇóÓë·µ»ØÊý¾Ý (×¢Ò⿪ÆôȨÏÞ£¬²»È»±¾µØÎÞ·¨Ð´Èë) +// 记录请求与返回数æ�® (注æ„�å¼€å�¯æ�ƒé™�,ä¸�然本地无法写入) app.UseRequestResponseLog(); -// Óû§·ÃÎʼǼ(±ØÐë·Åµ½Íâ²ã£¬²»È»Èç¹ûÓöµ½Òì³££¬»á±¨´í£¬ÒòΪ²»ÄÜ·µ»ØÁ÷)(×¢Ò⿪ÆôȨÏÞ£¬²»È»±¾µØÎÞ·¨Ð´Èë) +// 用户访问记录(必须放到外层,ä¸�然如果é�‡åˆ°å¼‚常,会报错,因为ä¸�能返回æµ�)(注æ„�å¼€å�¯æ�ƒé™�,ä¸�然本地无法写入) app.UseRecordAccessLogsMildd(); -// ¼Ç¼ipÇëÇó (×¢Ò⿪ÆôȨÏÞ£¬²»È»±¾µØÎÞ·¨Ð´Èë) +// 记录ip请求 (注æ„�å¼€å�¯æ�ƒé™�,ä¸�然本地无法写入) app.UseIpLogMildd(); app.UseSwagger().UseSwaggerUI(c => { - //¸ù¾Ý°æ±¾Ãû³Æµ¹Ðò ±éÀúչʾ + //æ ¹æ�®ç‰ˆæœ¬å��称倒åº� é��历展示 typeof(CustomApiVersion.ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach( version => { @@ -160,12 +160,12 @@ app.UseSwagger().UseSwaggerUI(c => c.RoutePrefix = "doc"; }); -//ʹÓà Session +//使用 Session app.UseSession(); if (app.Environment.IsDevelopment()) { - // ÔÚ¿ª·¢»·¾³ÖУ¬Ê¹ÓÃÒì³£Ò³Ãæ£¬ÕâÑù¿ÉÒÔ±©Â¶´íÎó¶ÑÕ»ÐÅÏ¢£¬ËùÒÔ²»Òª·ÅÔÚÉú²ú»·¾³¡£ + // 在开å�‘环境中,使用异常页é�¢ï¼Œè¿™æ ·å�¯ä»¥æš´éœ²é”™è¯¯å †æ ˆä¿¡æ�¯ï¼Œæ‰€ä»¥ä¸�è¦�放在生产环境。 app.UseDeveloperExceptionPage(); } else @@ -175,29 +175,29 @@ else app.UseHsts(); } -// CORS¿çÓò +// CORS跨域 app.UseCors(AppSettingsConstVars.CorsPolicyName); -// Ìø×ªhttps +// 跳转https //app.UseHttpsRedirection(); -// ʹÓþ²Ì¬Îļþ +// 使用é�™æ€�文件 app.UseStaticFiles(); -// ʹÓÃcookie +// 使用cookie app.UseCookiePolicy(); -// ·µ»Ø´íÎóÂë +// 返回错误ç � app.UseStatusCodePages(); // Routing app.UseRouting(); -// ÏÈ¿ªÆôÈÏÖ¤ +// 先开å�¯è®¤è¯� app.UseAuthentication(); -// È»ºóÊÇÊÚȨÖмä¼þ +// ç„¶å�Žæ˜¯æŽˆæ�ƒä¸­é—´ä»¶ app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); -//ÉèÖÃĬÈÏÆðʼҳ£¨Èçdefault.html£© -//´Ë´¦µÄ·¾¶ÊÇÏà¶ÔÓÚwwwrootÎļþ¼ÐµÄÏà¶Ô·¾¶ +//设置默认起始页(如default.html) +//此处的路径是相对于wwwroot文件夹的相对路径 var defaultFilesOptions = new DefaultFilesOptions(); defaultFilesOptions.DefaultFileNames.Clear(); defaultFilesOptions.DefaultFileNames.Add("index.html"); @@ -206,16 +206,16 @@ app.UseStaticFiles(); try { - //È·±£NLog.configÖÐÁ¬½Ó×Ö·û´®Óëappsettings.jsonÖÐͬ²½ + //ç¡®ä¿�NLog.config中连接字符串与appsettings.json中å�Œæ­¥ NLogUtil.EnsureNlogConfig("NLog.config"); - //ÆäËûÏîÄ¿Æô¶¯Ê±ÐèÒª×öµÄÊÂÇé - NLogUtil.WriteAll(NLog.LogLevel.Trace, LogType.ApiRequest, "½Ó¿ÚÆô¶¯", "½Ó¿ÚÆô¶¯³É¹¦"); + //其他项目å�¯åŠ¨æ—¶éœ€è¦�å�šçš„事情 + NLogUtil.WriteAll(NLog.LogLevel.Trace, LogType.ApiRequest, "接å�£å�¯åЍ", "接å�£å�¯åЍæˆ�功"); app.Run(); } catch (Exception ex) { - //ʹÓÃNlogдµ½±¾µØÈÕÖ¾Îļþ£¨ÍòÒ»Êý¾Ý¿âû´´½¨/Á¬½Ó³É¹¦£© - NLogUtil.WriteFileLog(NLog.LogLevel.Error, LogType.ApiRequest, "½Ó¿ÚÆô¶¯", "³õʼ»¯Êý¾ÝÒì³£", ex); + //使用Nlog写到本地日志文件(万一数æ�®åº“没创建/连接æˆ�功) + NLogUtil.WriteFileLog(NLog.LogLevel.Error, LogType.ApiRequest, "接å�£å�¯åЍ", "åˆ�始化数æ�®å¼‚常", ex); throw; } diff --git a/CoreCms.Net.Web.WebApi/Program.cs b/CoreCms.Net.Web.WebApi/Program.cs index da3b70d..a99e48b 100644 --- a/CoreCms.Net.Web.WebApi/Program.cs +++ b/CoreCms.Net.Web.WebApi/Program.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using Autofac; using Autofac.Extensions.DependencyInjection; @@ -35,96 +35,96 @@ using NLog.Web; var builder = WebApplication.CreateBuilder(args); -//Ìí¼Ó±¾µØÂ·¾¶»ñȡ֧³Ö +//添加本地路径获å�–支æŒ� builder.Services.AddSingleton(new AppSettingsHelper(builder.Environment.ContentRootPath, builder.Environment.EnvironmentName)); builder.Services.AddSingleton(new LogLockHelper(builder.Environment.ContentRootPath)); -//Memory»º´æ +//Memory缓存 builder.Services.AddMemoryCacheSetup(); -//Redis»º´æ +//Redis缓存 builder.Services.AddRedisCacheSetup(); -//Ìí¼ÓÊý¾Ý¿âÁ¬½ÓSqlSugar×¢ÈëÖ§³Ö +//添加数æ�®åº“连接SqlSugar注入支æŒ� builder.Services.AddSqlSugarSetup(); -//ÅäÖÿçÓò£¨CORS£© +//é…�置跨域(CORS) builder.Services.AddCorsSetup(); -//Ìí¼ÓsessionÖ§³Ö(sessionÒÀÀµÓÚcache½øÐд洢) +//添加session支æŒ�(sessionä¾�赖于cache进行存储) builder.Services.AddSession(); -// AutoMapperÖ§³Ö -// AutoMapperÖ§³Ö£¨15°æ±¾ºóÆôÓÃÁËÊÚȨģʽ£¬´ó¼Ò¿ÉÒÔǰÍùhttps://luckypennysoftware.com/ÉêÇë×Ô¼ºÃâ·ÑµÄkey£© +// AutoMapper支æŒ� +// AutoMapper支æŒ�(15版本å�Žå�¯ç”¨äº†æŽˆæ�ƒæ¨¡å¼�,大家å�¯ä»¥å‰�å¾€https://luckypennysoftware.com/申请自己å…�费的key) //builder.Services.AddAutoMapper(typeof(AutoMapperConfiguration)); builder.Services.AddAutoMapper(cfg => cfg.LicenseKey = AppSettingsConstVars.AutoMapperLicenseKey, typeof(AutoMapperConfiguration)); -//MediatR£¨Ö»ÐèҪע²áÒ»¸ö,ͬÏîÄ¿»òÀà¿âϾͲ»ÐèҪע²á¶à¸ö£© +//MediatR(å�ªéœ€è¦�注册一个,å�Œé¡¹ç›®æˆ–类库下就ä¸�需è¦�注册多个) builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(TextMessageEventCommand).Assembly)); -//ʹÓà SignalR +//使用 SignalR builder.Services.AddSignalR(); -//RedisÏûÏ¢¶ÓÁÐ +//Redis消æ�¯é˜Ÿåˆ— builder.Services.AddRedisMessageQueueSetup(); -// ÒýÈëPayment ÒÀÀµ×¢Èë(Ö§¸¶±¦Ö§¸¶/΢ÐÅÖ§¸¶) +// 引入Payment ä¾�赖注入(支付å®�支付/微信支付) builder.Services.AddAlipay(); builder.Services.AddWeChatPay(); -// ÔÚ appsettings.json ÖÐ ÅäÖÃÑ¡Ïî +// 在 appsettings.json 中 é…�置选项 builder.Services.Configure(builder.Configuration.GetSection("WeChatPay")); builder.Services.Configure(builder.Configuration.GetSection("Alipay")); -//×¢²á×Ô¶¨Òå΢ÐŽӿÚÅäÖÃÎļþ +//注册自定义微信接å�£é…�置文件 builder.Services.Configure(builder.Configuration.GetSection(nameof(CoreCms.Net.WeChat.Service.Options.WeChatOptions))); -// ×¢È빤³§ HTTP ¿Í»§¶Ë +// 注入工厂 HTTP 客户端 builder.Services.AddHttpClient(); builder.Services.AddSingleton(); -//Swagger½Ó¿ÚÎĵµ×¢Èë +//Swagger接å�£æ–‡æ¡£æ³¨å…¥ builder.Services.AddClientSwaggerSetup(); -//ÅäÖÃÒ×ÁªÔÆ´òÓ¡»ú +//é…�置易è�”云打å�°æœº builder.Services.AddYiLianYunSetup(); -//×¢²áHangfire¶¨Ê±ÈÎÎñ +//注册Hangfire定时任务 builder.Services.AddHangFireSetup(); -//ÊÚȨ֧³Ö×¢Èë +//授æ�ƒæ”¯æŒ�注入 builder.Services.AddAuthorizationSetupForClient(); -//ÉÏÏÂÎÄ×¢Èë +//上下文注入 builder.Services.AddHttpContextSetup(); -//·þÎñÅäÖÃÖмÓÈëAutoFac¿ØÖÆÆ÷Ìæ»»¹æÔò¡£ +//æœ�务é…�置中加入AutoFac控制器替æ�¢è§„则。 builder.Services.Replace(ServiceDescriptor.Transient()); -//×¢²ámvc£¬×¢²árazorÒýÇæÊÓͼ +//注册mvc,注册razor引擎视图 builder.Services.AddMvc(options => { - //ʵÌåÑéÖ¤ + //实体验è¯� options.Filters.Add(); - //Òì³£´¦Àí + //异常处ç�† options.Filters.Add(); - //SwaggerÌÞ³ý²»ÐèÒª¼ÓÈëapiչʾµÄÁбí + //Swagger剔除ä¸�需è¦�加入api展示的列表 options.Conventions.Add(new ApiExplorerIgnores()); }) .AddNewtonsoftJson(p => { - //Êý¾Ý¸ñʽÊ××ÖĸСд ²»Ê¹ÓÃÍÕ·å + //æ•°æ�®æ ¼å¼�首字æ¯�å°�写 ä¸�使用驼峰 p.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); - //²»Ê¹ÓÃÍÕ·åÑùʽµÄkey + //ä¸�使用驼峰样å¼�çš„key //p.SerializerSettings.ContractResolver = new DefaultContractResolver(); - //ºöÂÔÑ­»·ÒýÓà + //忽略循环引用 p.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; - //ÉèÖÃʱ¼ä¸ñʽ£¨±ØÐëʹÓÃyyyy/MM/dd¸ñʽ£¬ÒòΪiosϵͳ²»Ö§³Ö2018-03-29¸ñʽµÄʱ¼ä£¬Ö»Ê¶±ð2018/03/09ÕâÖÖ¸ñʽ¡££© + //设置时间格å¼�(必须使用yyyy/MM/ddæ ¼å¼�,因为ios系统ä¸�支æŒ�2018-03-29æ ¼å¼�的时间,å�ªè¯†åˆ«2018/03/09è¿™ç§�æ ¼å¼�。) p.SerializerSettings.DateFormatString = "yyyy/MM/dd HH:mm:ss"; }); -#region AutoFac×¢²á============================================================================ +#region AutoFac注册============================================================================ builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); builder.Host.ConfigureContainer(containerBuilder => { - //»ñÈ¡ËùÓпØÖÆÆ÷ÀàÐͲ¢Ê¹ÓÃÊôÐÔ×¢Èë + //获å�–所有控制器类型并使用属性注入 var controllerBaseType = typeof(ControllerBase); containerBuilder.RegisterAssemblyTypes(typeof(Program).Assembly) .Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType) @@ -138,39 +138,39 @@ builder.Host.ConfigureContainer(containerBuilder => var app = builder.Build(); -#region ½â¾öUbuntu Nginx ´úÀí²»ÄÜ»ñÈ¡IPÎÊÌâ +#region 解决Ubuntu Nginx 代ç�†ä¸�能获å�–IP问题 app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); #endregion -// ¼Ç¼ÇëÇóÓë·µ»ØÊý¾Ý (×¢Ò⿪ÆôȨÏÞ£¬²»È»±¾µØÎÞ·¨Ð´Èë) +// 记录请求与返回数æ�® (注æ„�å¼€å�¯æ�ƒé™�,ä¸�然本地无法写入) app.UseRequestResponseLog(); -// Óû§·ÃÎʼǼ(±ØÐë·Åµ½Íâ²ã£¬²»È»Èç¹ûÓöµ½Òì³££¬»á±¨´í£¬ÒòΪ²»ÄÜ·µ»ØÁ÷)(×¢Ò⿪ÆôȨÏÞ£¬²»È»±¾µØÎÞ·¨Ð´Èë) +// 用户访问记录(必须放到外层,ä¸�然如果é�‡åˆ°å¼‚常,会报错,因为ä¸�能返回æµ�)(注æ„�å¼€å�¯æ�ƒé™�,ä¸�然本地无法写入) app.UseRecordAccessLogsMildd(); -// ¼Ç¼ipÇëÇó (×¢Ò⿪ÆôȨÏÞ£¬²»È»±¾µØÎÞ·¨Ð´Èë) +// 记录ip请求 (注æ„�å¼€å�¯æ�ƒé™�,ä¸�然本地无法写入) app.UseIpLogMildd(); -// SwaggerÊÚȨµÇ¼À¹½Ø +// Swagger授æ�ƒç™»å½•拦截 app.UseSwaggerAuthorizedMildd(); -//Ç¿ÖÆÏÔʾÖÐÎÄ +//强制显示中文 System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-CN"); app.UseSwagger().UseSwaggerUI(c => { - //¸ù¾Ý°æ±¾Ãû³Æµ¹Ðò ±éÀúչʾ + //æ ¹æ�®ç‰ˆæœ¬å��称倒åº� é��历展示 typeof(CustomApiVersion.ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach( version => { c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"Doc {version}"); }); - //ÉèÖÃĬÈÏÌø×ªµ½swagger-ui + //设置默认跳转到swagger-ui c.RoutePrefix = AppSettingsConstVars.SwaggerRoutePrefix; }); -#region Hangfire¶¨Ê±ÈÎÎñ +#region Hangfire定时任务 -//ÊÚȨ +//授æ�ƒ var filter = new BasicAuthAuthorizationFilter( new BasicAuthAuthorizationFilterOptions { @@ -191,8 +191,8 @@ var filter = new BasicAuthAuthorizationFilter( }); var hangfireOptions = new Hangfire.DashboardOptions { - AppPath = "/",//·µ»ØÊ±Ìø×ªµÄµØÖ· - DisplayStorageConnectionString = false,//ÊÇ·ñÏÔʾÊý¾Ý¿âÁ¬½ÓÐÅÏ¢ + AppPath = "/",//返回时跳转的地å�€ + DisplayStorageConnectionString = false,//是å�¦æ˜¾ç¤ºæ•°æ�®åº“连接信æ�¯ Authorization = new[] { filter @@ -203,18 +203,18 @@ var hangfireOptions = new Hangfire.DashboardOptions app.UseHangfireDashboard(AppSettingsConstVars.HangFireRoutePrefix, hangfireOptions); HangfireDispose.HangfireService(); -//ÉèÖÃhangfire¶¨Ê±ÈÎÎñ¹ýÆÚʱ¼ä +//设置hangfire定时任务过期时间 GlobalStateHandlers.Handlers.Add(new SucceededStateExpireHandler(AppSettingsConstVars.HangFireJobExpirationTimeOut)); #endregion -//ʹÓà Session +//使用 Session app.UseSession(); if (app.Environment.IsDevelopment()) { - // ÔÚ¿ª·¢»·¾³ÖУ¬Ê¹ÓÃÒì³£Ò³Ãæ£¬ÕâÑù¿ÉÒÔ±©Â¶´íÎó¶ÑÕ»ÐÅÏ¢£¬ËùÒÔ²»Òª·ÅÔÚÉú²ú»·¾³¡£ + // 在开å�‘环境中,使用异常页é�¢ï¼Œè¿™æ ·å�¯ä»¥æš´éœ²é”™è¯¯å †æ ˆä¿¡æ�¯ï¼Œæ‰€ä»¥ä¸�è¦�放在生产环境。 app.UseDeveloperExceptionPage(); } else @@ -224,25 +224,25 @@ else app.UseHsts(); } -// CORS¿çÓò +// CORS跨域 app.UseCors(AppSettingsConstVars.CorsPolicyName); // Routing app.UseRouting(); -// ʹÓþ²Ì¬Îļþ +// 使用é�™æ€�文件 app.UseStaticFiles(); -// ÏÈ¿ªÆôÈÏÖ¤ +// 先开å�¯è®¤è¯� app.UseAuthentication(); -// È»ºóÊÇÊÚȨÖмä¼þ +// ç„¶å�Žæ˜¯æŽˆæ�ƒä¸­é—´ä»¶ app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); -//ÉèÖÃĬÈÏÆðʼҳ£¨Èçdefault.html£© -//´Ë´¦µÄ·¾¶ÊÇÏà¶ÔÓÚwwwrootÎļþ¼ÐµÄÏà¶Ô·¾¶ +//设置默认起始页(如default.html) +//此处的路径是相对于wwwroot文件夹的相对路径 var defaultFilesOptions = new DefaultFilesOptions(); defaultFilesOptions.DefaultFileNames.Clear(); defaultFilesOptions.DefaultFileNames.Add("index.html"); @@ -251,16 +251,16 @@ app.UseStaticFiles(); try { - //È·±£NLog.configÖÐÁ¬½Ó×Ö·û´®Óëappsettings.jsonÖÐͬ²½ + //ç¡®ä¿�NLog.config中连接字符串与appsettings.json中å�Œæ­¥ NLogUtil.EnsureNlogConfig("NLog.config"); - //ÆäËûÏîÄ¿Æô¶¯Ê±ÐèÒª×öµÄÊÂÇé - NLogUtil.WriteAll(NLog.LogLevel.Trace, LogType.ApiRequest, "½Ó¿ÚÆô¶¯", "½Ó¿ÚÆô¶¯³É¹¦"); + //其他项目å�¯åŠ¨æ—¶éœ€è¦�å�šçš„事情 + NLogUtil.WriteAll(NLog.LogLevel.Trace, LogType.ApiRequest, "接å�£å�¯åЍ", "接å�£å�¯åЍæˆ�功"); app.Run(); } catch (Exception ex) { - //ʹÓÃNlogдµ½±¾µØÈÕÖ¾Îļþ£¨ÍòÒ»Êý¾Ý¿âû´´½¨/Á¬½Ó³É¹¦£© - NLogUtil.WriteFileLog(NLog.LogLevel.Error, LogType.ApiRequest, "½Ó¿ÚÆô¶¯", "³õʼ»¯Êý¾ÝÒì³£", ex); + //使用Nlog写到本地日志文件(万一数æ�®åº“没创建/连接æˆ�功) + NLogUtil.WriteFileLog(NLog.LogLevel.Error, LogType.ApiRequest, "接å�£å�¯åЍ", "åˆ�始化数æ�®å¼‚常", ex); throw; }