TheRegister.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. using Blazored.LocalStorage;
  2. using EasyTemplate.Blazor.Web.Components;
  3. using EasyTemplate.Page.Common;
  4. using EasyTemplate.Service.Common;
  5. using EasyTemplate.Tool;
  6. using EasyTemplate.Tool.Util;
  7. using Microsoft.AspNetCore.Authentication.Cookies;
  8. using Microsoft.AspNetCore.Components.Authorization;
  9. using Microsoft.AspNetCore.Identity;
  10. using Microsoft.AspNetCore.Mvc.ApplicationModels;
  11. using Microsoft.AspNetCore.StaticFiles;
  12. using Microsoft.Extensions.FileProviders;
  13. using Microsoft.OpenApi.Models;
  14. using System.Net;
  15. using System.Net.Sockets;
  16. using System.Reflection;
  17. using System.Text;
  18. using EasyTemplate.Service;
  19. namespace EasyTemplate.Blazor.Web.Common;
  20. public static class TheRegister
  21. {
  22. /// <summary>
  23. /// 注册配置
  24. /// </summary>
  25. /// <param name="builder"></param>
  26. /// <returns></returns>
  27. public static WebApplicationBuilder? RegistService(this WebApplicationBuilder? builder)
  28. {
  29. var configuration = builder.Configuration;
  30. // Add services to the container.
  31. builder.Services.AddRazorComponents()
  32. .AddInteractiveServerComponents();
  33. builder.Services.AddConfiguration();
  34. builder.Services.AddLocalLog();
  35. builder.Services.AddSqlSugar();
  36. builder.Services.AddRedis();
  37. builder.Services.AddAntDesign();
  38. builder.Services.AddInteractiveStringLocalizer();
  39. builder.Services.AddLocalization();
  40. builder.Services.AddHttpContextAccessor();
  41. builder.Services.AddCors(options =>
  42. {
  43. options.AddPolicy("Policy", policy =>
  44. {
  45. policy.AllowAnyOrigin()
  46. .AllowAnyMethod()
  47. .AllowAnyHeader();
  48. });
  49. });
  50. builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
  51. .AddCookie(options =>
  52. {
  53. options.LoginPath = "/account/login"; // 登录页路径
  54. options.AccessDeniedPath = "/error/404"; // 未授权页路径
  55. options.SlidingExpiration = true; // 滑动过期
  56. });
  57. builder.Services.AddRazorPages();
  58. builder.Services.AddServerSideBlazor();
  59. builder.Services.AddAuthorization();
  60. builder.Services.Configure<ProSettings>(Setting.GetSection("ThemeSettings"));
  61. Global.SystemName = Setting.Get<string>("ThemeSettings:Title");
  62. builder.Services.AddControllers().AddNewtonsoftJson();//不加该注册,api传参易报错
  63. builder.Services.AddEndpointsApiExplorer();
  64. builder.Services.AddSwaggerGen(options =>
  65. {
  66. typeof(ApiGroupNames).GetFields().Skip(1).ToList().ForEach(f =>
  67. {
  68. //获取枚举值上的特性
  69. var info = f.GetCustomAttributes(typeof(GroupInfoAttribute), false).OfType<GroupInfoAttribute>().FirstOrDefault();
  70. options.SwaggerDoc(f.Name, new Microsoft.OpenApi.Models.OpenApiInfo
  71. {
  72. Title = info?.Title,
  73. Version = info?.Version,
  74. Description = info?.Description
  75. });
  76. });
  77. options.SwaggerDoc("all", new Microsoft.OpenApi.Models.OpenApiInfo
  78. {
  79. Title = "全部"
  80. });
  81. options.DocInclusionPredicate((docName, apiDescription) =>
  82. {
  83. if (docName != "all")
  84. {
  85. return apiDescription.GroupName == docName;
  86. }
  87. return true;
  88. });
  89. options.AddSecurityDefinition("Bearer", new Microsoft.OpenApi.Models.OpenApiSecurityScheme()
  90. {
  91. Description = "请输入正确的Token格式:Bearer token",
  92. Name = "Authorization",
  93. In = Microsoft.OpenApi.Models.ParameterLocation.Header,
  94. Type = Microsoft.OpenApi.Models.SecuritySchemeType.ApiKey,
  95. BearerFormat = "JWT",
  96. Scheme = "Bearer"
  97. });
  98. //options.DocInclusionPredicate((docName, description) => true);
  99. options.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement() {
  100. {
  101. new OpenApiSecurityScheme
  102. {
  103. Reference = new OpenApiReference()
  104. {
  105. Type = ReferenceType.SecurityScheme,
  106. Id = "Bearer"
  107. }
  108. },
  109. new string[]{ }
  110. }
  111. });
  112. var baseDirectory = System.AppDomain.CurrentDomain.BaseDirectory;
  113. var xmlFile = System.AppDomain.CurrentDomain.FriendlyName + ".xml";
  114. var xmlPath = Path.Combine(baseDirectory, xmlFile);
  115. options.IncludeXmlComments(xmlPath);
  116. });
  117. //将类库中razor注册到应用中
  118. builder.Services.AddAssembly();
  119. builder.Services.AddDynamicController<ServiceLocalSelectController, ServiceActionRouteFactory>();
  120. //builder.Services.AddCascadingAuthenticationState();
  121. //builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthenticationStateProvider>();
  122. builder.Services.AddScoped<CustomAuthenticationStateProvider>();
  123. builder.Services.AddScoped<AuthenticationStateProvider>(implementationFactory => implementationFactory.GetRequiredService<CustomAuthenticationStateProvider>());
  124. // 注册 Blazored.LocalStorage 服务
  125. builder.Services.AddBlazoredLocalStorage();
  126. builder.Services.AddSingleton<INotificationService, NotificationService>();
  127. //builder.Services.AddSingleton<UdpServerService>();
  128. // 在 Startup.cs 或 Program.cs 中注册
  129. //builder.Services.AddScoped<IHostedService, UdpServerService>();
  130. // builder.Services.AddHostedService<UdpServerService>();
  131. // 注册后台UDP监听服务
  132. builder.Services.AddSingleton<UdpListenerService>();
  133. builder.Services.AddHostedService(sp => sp.GetRequiredService<UdpListenerService>());
  134. //builder.Services.AddHostedService<BackgroundTimerService>();
  135. //builder.Services.AddScoped<IBackgroundService>(provider =>
  136. // provider.GetRequiredService<BackgroundTimerService>());
  137. // 注册UDP服务
  138. //builder.Services.AddScoped<IUdpService, UdpService>();
  139. //builder.Services.AddScoped<UdpBroadcastService>();
  140. /*
  141. UdpClient udpServer = new UdpClient(10000);
  142. IPEndPoint clientEndPoint = new IPEndPoint(IPAddress.Any, 0);
  143. Console.WriteLine("UDP Server started on port 10000...");
  144. while (true)
  145. {
  146. try
  147. {
  148. byte[] receiveBytes = udpServer.Receive(ref clientEndPoint);
  149. string receivedData = Encoding.UTF8.GetString(receiveBytes);
  150. Console.WriteLine($"Received: {receivedData} from {clientEndPoint}");
  151. string response = "Echo: " + receivedData;
  152. byte[] sendBytes = Encoding.UTF8.GetBytes(response);
  153. udpServer.Send(sendBytes, sendBytes.Length, clientEndPoint);
  154. }
  155. catch (Exception e)
  156. {
  157. Console.WriteLine("Error: " + e.Message);
  158. }
  159. }
  160. */
  161. return builder;
  162. }
  163. /// <summary>
  164. /// 注册应用
  165. /// </summary>
  166. /// <param name="builder"></param>
  167. /// <returns></returns>
  168. public static WebApplicationBuilder? RegistApp(this WebApplicationBuilder? builder)
  169. {
  170. var app = builder.Build();
  171. // Configure the HTTP request pipeline.
  172. if (!app.Environment.IsDevelopment())
  173. {
  174. app.UseExceptionHandler("/Error", createScopeForErrors: true);
  175. }
  176. app.UseStatusCodePagesWithReExecute("/error/{0}");
  177. app.UseSwagger();
  178. app.UseSwaggerUI(options =>
  179. {
  180. //遍历ApiGroupNames所有枚举值生成接口文档,Skip(1)是因为Enum第一个FieldInfo是内置的一个Int值
  181. typeof(ApiGroupNames).GetFields().Skip(1).ToList().ForEach(f =>
  182. {
  183. //获取枚举值上的特性
  184. var info = f.GetCustomAttributes(typeof(GroupInfoAttribute), false).OfType<GroupInfoAttribute>().FirstOrDefault();
  185. options.SwaggerEndpoint($"/swagger/{f.Name}/swagger.json", info != null ? info.Title : f.Name);
  186. });
  187. options.SwaggerEndpoint("/swagger/all/swagger.json", "全部");
  188. });
  189. app.UseStaticFiles();
  190. app.UseCors("Policy");
  191. app.UseDynamicWebApi();
  192. app.UseHttpsRedirection();
  193. app.UseRouting();
  194. app.UseAuthentication();
  195. app.UseAuthorization();
  196. app.UseAntiforgery();
  197. app.MapRazorComponents<App>()
  198. .AddInteractiveServerRenderMode();
  199. app.MapControllers();
  200. //UdpServer server = new UdpServer(); // 创建UdpServer实例并启动监听线程
  201. //Console.WriteLine("UDP Server is running...");
  202. // Console.ReadLine(); // 等待用户输入以保持程序运行,以便可以看到输出结果。实际应用中可以根据需要调整。
  203. // server.StopServer(); // 在需要停止服务器时调用此方法,例如在程序结束时。
  204. app.Run();
  205. return builder;
  206. }
  207. private static FileExtensionContentTypeProvider GetFileExtensionContentTypeProvider()
  208. {
  209. var provider = new FileExtensionContentTypeProvider();
  210. provider.Mappings[".iec"] = "application/octet-stream";
  211. provider.Mappings[".patch"] = "application/octet-stream";
  212. provider.Mappings[".apk"] = "application/vnd.android.package-archive";
  213. provider.Mappings[".pem"] = "application/x-x509-user-cert";
  214. provider.Mappings[".gzip"] = "application/x-gzip";
  215. provider.Mappings[".7zip"] = "application/zip";
  216. provider.Mappings[".jpg2"] = "image/jp2";
  217. provider.Mappings[".et"] = "application/kset";
  218. provider.Mappings[".dps"] = "application/ksdps";
  219. provider.Mappings[".cdr"] = "application/x-coreldraw";
  220. provider.Mappings[".shtml"] = "text/html";
  221. provider.Mappings[".php"] = "application/x-httpd-php";
  222. provider.Mappings[".php3"] = "application/x-httpd-php";
  223. provider.Mappings[".php4"] = "application/x-httpd-php";
  224. provider.Mappings[".phtml"] = "application/x-httpd-php";
  225. provider.Mappings[".pcd"] = "image/x-photo-cd";
  226. provider.Mappings[".bcmap"] = "application/octet-stream";
  227. provider.Mappings[".properties"] = "application/octet-stream";
  228. provider.Mappings[".m3u8"] = "application/x-mpegURL";
  229. return provider;
  230. }
  231. }
  232. internal class ServiceLocalSelectController : ISelectController
  233. {
  234. public bool IsController(Type type)
  235. {
  236. return type.IsPublic && type.GetCustomAttribute<DynamicControllerAttribute>() != null;
  237. }
  238. }
  239. internal class ServiceActionRouteFactory : IActionRouteFactory
  240. {
  241. public string CreateActionRouteModel(string areaName, string controllerName, ActionModel action)
  242. {
  243. var controllerType = action.ActionMethod.DeclaringType;
  244. var serviceAttribute = controllerType.GetCustomAttribute<DynamicControllerAttribute>();
  245. var _controllerName = serviceAttribute.ServiceName == string.Empty ? controllerName.Replace("Service", "") : serviceAttribute.ServiceName.Replace("Service", "");
  246. return $"api/{_controllerName.Replace("Service", "")}/{action.ActionName.Replace("Async", "")}";
  247. }
  248. }