网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
using System.Text.Json.Serialization;
using AgileConfig.Client;
using Dpz.Core.Hangfire;
using Dpz.Core.Infrastructure.Configuration;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Scalar.AspNetCore;

const string originsName = "Open";
Log.Logger = new LoggerConfiguration().Enrich.FromLogContext().CreateBootstrapLogger();
try
{
    var builder = WebApplication.CreateBuilder(args);
    builder.Host.UseAgileConfig(new ConfigClient(builder.Configuration));

    var configuration = builder.Configuration;

    var seq = configuration.GetSection("LogSeq").Get<LogSeq>();
    builder.Host.ConfigurationLog(seq);
    const int threads = 100;
    if (ThreadPool.SetMinThreads(threads, threads))
    {
        Log.Information(
            "set worker threads:{WorkerThreads},set completion  port threads {CompletionPortThreads}",
            threads,
            threads
        );
    }

    #region services

    var services = builder.Services;

    // IoC
    services.AddDefaultServices(configuration).AddAppScoped();

    services
        .AddControllers()
        // .AddXmlDataContractSerializerFormatters()
        .AddXmlSerializerFormatters()
        .AddMessagePackSerializerFormatters()
        .AddJsonOptions(opts =>
        {
            opts.JsonSerializerOptions.Converters.Add(new TimeSpanConverter());
            opts.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
        });

    services.AddResponseCompression(options =>
    {
        options.Providers.Add<BrotliCompressionProvider>();
        options.Providers.Add<GzipCompressionProvider>();
        options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
            new[] { "application/font-woff2", "image/svg+xml", "text/plain", "application/lrc" }
        );
    });

    services.Configure<BrotliCompressionProviderOptions>(options =>
    {
        options.Level = CompressionLevel.Optimal;
    });

    services.Configure<GzipCompressionProviderOptions>(options =>
    {
        options.Level = CompressionLevel.Optimal;
    });

    services.Configure<KestrelServerOptions>(options =>
    {
        options.Limits.MaxRequestBodySize = int.MaxValue;
    });

    services.AddEndpointsApiExplorer();
    services.AddSwaggerGen(options =>
    {
        var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
        var description = "";
        if (!string.IsNullOrEmpty(basePath))
        {
            var xmlPath = Path.Combine(basePath, "Dpz.Core.WebApi.xml");
            options.IncludeXmlComments(xmlPath);
            var viewModelXmlPath = Path.Combine(basePath, "Dpz.Core.Public.ViewModel.xml");
            options.IncludeXmlComments(viewModelXmlPath);

            var readmePath = Path.Combine(basePath, "README.md");
            if (File.Exists(readmePath))
            {
                description = File.ReadAllText(readmePath);
            }
        }
        options.SwaggerDoc(
            "v1",
            new OpenApiInfo
            {
                Title = "Dpz.Core.WebApi",
                Version = Assembly.GetEntryAssembly()?.GetName().Version?.ToString(),
                Description = description,
            }
        );

        options.AddSecurityDefinition(
            "Bearer",
            new OpenApiSecurityScheme
            {
                Description = "使用Bearer方案的JWT授权标头(示例:“ Bearer JWT_Token”)",
                Name = "Authorization",
                In = ParameterLocation.Header,
                Type = SecuritySchemeType.ApiKey,
                Scheme = "Bearer",
            }
        );

        options.AddSecurityRequirement(
            new OpenApiSecurityRequirement
            {
                {
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference
                        {
                            Type = ReferenceType.SecurityScheme,
                            Id = "Bearer",
                        },
                    },
                    Array.Empty<string>()
                },
            }
        );
    });

    //缓存
    services.AddRedisCacheOutput(configuration.GetConnectionString("redis"));
    services.AddBusinessServices(configuration);

    // Cors
    services.AddCors(options =>
    {
        options.AddPolicy(
            originsName,
            cfg =>
            {
                cfg.WithOrigins(configuration.GetSection("Origins").Get<string[]>())
                    .WithMethods("GET", "PUT", "POST", "DELETE", "PATCH")
                    .AllowAnyHeader();
            }
        );
    });

    services.Configure<TokenManagement>(configuration.GetSection("TokenManagement"));

    services
        .AddAuthentication(x =>
        {
            x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(x =>
        {
            var token = configuration.GetSection("TokenManagement").Get<TokenManagement>();
            x.RequireHttpsMetadata = true;
            x.SaveToken = true;
            x.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(token.Secret)),
                ValidIssuer = token.Issuer,
                ValidAudience = token.Audience,
                ValidateIssuer = true,
                ValidateAudience = true,
            };
        });
    services.AddDataProtection().SetApplicationName(AuthorizeCookieName);
    services
        .AddOptions<KeyManagementOptions>()
        .Configure<IServiceScopeFactory>(
            (options, factory) =>
            {
                options.XmlRepository = new XmlRepositoryService(
                    factory,
                    AuthorizeCookieName + ".Key"
                );
            }
        );
    services.AddAuthorization(options =>
    {
        options.AddPolicy(
            ApiPermission.System,
            policy => policy.Requirements.Add(new PermissionRequirement(Permissions.System))
        );
    });

    services.AddRazorPages(x =>
    {
        x.Conventions.AddPageRoute("/SignIn", "signIn.html");
    });

    var webApiHangfireCollectionPrefix =
        configuration["WebApiHangfireCollectionPrefix"] ?? throw new InvalidConfigurationException();
    services.AddHangfireService(configuration, webApiHangfireCollectionPrefix);

    #endregion
    
    var app = builder.Build();

    #region configuration

    if (app.Environment.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseSerilogRequestLogging(options =>
    {
        options.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
        {
            diagnosticContext.Set("RequestHost", httpContext.Request.Host.Value);
            diagnosticContext.Set("RequestScheme", httpContext.Request.Scheme);
            diagnosticContext.Set(
                "UserAgent",
                httpContext.Request.Headers["User-Agent"].ToString()
            );
            diagnosticContext.Set("IpAddress", httpContext.Request.GetIpAddress());
        };
    });

    app.UseResponseHeaders().UseRequestRecord().UseDateTimeLocalFormat();

    app.UseResponseCompression();

    app.UseSwagger(options =>
    {
        options.RouteTemplate = "{documentName}/open-api.json";
    });

    // app.UseSwaggerUI(options =>
    // {
    //     options.RoutePrefix = "";
    //     options.SwaggerEndpoint("/v1/open-api.json", "Dpz.Core.WebApi v1");
    //     options.InjectStylesheet("https://dpangzi.com/darkmode/theme-material.css");
    // });
    app.MapScalarApiReference(options =>
    {
        options.Title = "Dpz.Core.WebApi v1";
        options.WithOpenApiRoutePattern("/v1/open-api.json");
        options.Favicon = "https://dpangzi.com/favicon.ico";
        options.Theme = ScalarTheme.Moon;
        options.HideDarkModeToggle = false;
    });

    app.GetHostingEnvironment();

    // //强制HTTPS
    // app.UseHttpsRedirection();

    app.UseRouting();

    app.MapRazorPages();

    app.UseCors(originsName);

    //身份认证
    app.UseAuthentication();
    //身份授权
    app.UseAuthorization();

    app.MapControllers();
    //app.UseEndpoints(endpoints => { endpoints.MapControllers(); });

#if DEBUG
    app.HangfireSetting();
#endif

    #endregion

    app.MapGet("/ping", () => "pong");
    app.MapGet("/datetime", () => $"{DateTime.Now:yyyy/Mm/dd HH:mm:ss}\r\n{Environment.MachineName}");
    Log.Information("Starting web api host,current process id:{ID}", Environment.ProcessId);
    app.Run();
}
catch (Exception e)
{
    Console.Error.WriteLine(e);
    Log.Fatal(e, "Host terminated unexpectedly");
}

/// <summary>
///
/// </summary>
public partial class Program
{
    /// <summary>
    /// 身份认证Cookie名称
    /// </summary>
    public const string AuthorizeCookieName = "Dpz.Web.Api.Server.Authoriza";

    /// <summary>
    /// 账号Cookie名称
    /// </summary>
    public const string AccountCookieName = "Dpz.Web.Api.Server.Account";
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

这段代码是一个 ASP.NET Core Web API 应用程序的启动代码,主要功能包括配置服务、设置中间件、处理请求和响应等。以下是对代码的详细解释:

1. 引入命名空间

代码开始部分引入了一些必要的命名空间,包括日志、配置、依赖注入、数据保护、Hangfire、Swagger等。

2. 日志配置

使用 Serilog 进行日志记录,创建一个引导日志记录器。

3. 创建 Web 应用程序

使用 WebApplication.CreateBuilder(args) 创建一个 Web 应用程序的构建器。

4. 配置 AgileConfig

通过 builder.Host.UseAgileConfig 使用 AgileConfig 进行配置管理。

5. 配置线程池

设置最小工作线程数,确保应用程序能够处理并发请求。

6. 服务配置

#region services 部分,配置了多个服务:

  • IoC 容器:使用 AddDefaultServicesAddAppScoped 方法注册默认服务和应用程序范围的服务。
  • 控制器:添加控制器支持,并配置 JSON、XML 和 MessagePack 序列化选项。
  • 响应压缩:配置 Brotli 和 Gzip 压缩。
  • Kestrel 服务器选项:设置最大请求体大小。
  • Swagger:配置 Swagger 文档生成,包括 API 文档和安全定义。
  • Redis 缓存:添加 Redis 缓存服务。
  • CORS:配置跨源资源共享策略。
  • 身份验证:使用 JWT Bearer 进行身份验证,配置 Token 管理。
  • 数据保护:配置数据保护服务。
  • 授权:添加授权策略。
  • Razor Pages:配置 Razor 页面路由。
  • Hangfire:配置 Hangfire 服务用于后台任务处理。

7. 中间件配置

#region configuration 部分,配置了中间件:

  • 开发环境异常页面:在开发环境中使用开发者异常页面。
  • 请求日志记录:使用 Serilog 记录请求日志。
  • 响应头、请求记录和日期时间格式:配置响应头、请求记录和日期时间格式。
  • 响应压缩:启用响应压缩。
  • Swagger UI:配置 Swagger UI 的路由。
  • API 路由:配置 API 路由和主题。
  • 强制 HTTPS:可以选择强制使用 HTTPS(注释掉了)。
  • 路由:启用路由功能。
  • CORS:使用配置的 CORS 策略。
  • 身份验证和授权:启用身份验证和授权中间件。
  • 控制器映射:映射控制器路由。

8. 其他功能

  • 提供了两个简单的 GET 路由 /ping/datetime,用于测试 API 是否正常工作。
  • 记录应用程序启动信息。

9. 异常处理

catch 块中捕获异常并记录错误信息。

10. 类定义

定义了一个 Program 类,包含一些常量用于身份认证和账号 Cookie 的名称。

总结

这段代码是一个完整的 ASP.NET Core Web API 应用程序的启动配置,涵盖了服务注册、中间件配置、日志记录、身份验证、授权、CORS、Swagger 文档生成等多个方面,旨在提供一个功能齐全的 Web API 服务。

loading