网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
using System.Security.Claims;
using Dpz.Core.WebApi.MessagePackFormatters;
using MessagePack.Resolvers;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;

#pragma warning disable CS0162

namespace Dpz.Core.WebApi;

/// <summary>
/// Tools Extensions
/// </summary>
public static class ToolsExtensions
{
    /// <summary>
    /// 根据Identity反射获取当前用户信息
    /// 未授权用户返回 null
    /// </summary>
    /// <param name="principal"></param>
    /// <returns></returns>
    public static VmUserInfo GetIdentity(this ClaimsPrincipal principal)
    {
        if (principal.Identity?.IsAuthenticated == true)
        {
            var userInfo = new VmUserInfo();
            foreach (var claims in principal.Claims)
            {
                var property = typeof(VmUserInfo).GetProperty(claims.Type);
                if (property == null)
                    continue;
                if (property.PropertyType == typeof(DateTime?))
                {
                    property.SetValue(userInfo, DateTime.Parse(claims.Value));
                }
                else if (property.PropertyType == typeof(Sex))
                {
                    var sex = Enum.Parse(typeof(Sex), claims.Value);
                    property.SetValue(userInfo, sex);
                }
                else if (property.PropertyType == typeof(bool?))
                {
                    bool.TryParse(claims.Value, out var result);
                    property.SetValue(userInfo, result);
                }
                else if (property.PropertyType == typeof(Permissions?))
                {
                    if (Enum.TryParse(claims.Value, out Permissions permissions))
                    {
                        property.SetValue(userInfo, permissions);
                    }
                }
                else
                {
                    typeof(VmUserInfo).GetProperty(claims.Type)?.SetValue(userInfo, claims.Value);
                }
            }

            return userInfo;
        }

        return null;
    }

    /// <summary>
    /// 生成翻页元数据
    /// </summary>
    /// <param name="pagedList"></param>
    /// <param name="header"></param>
    /// <returns></returns>
    public static void AddPaginationMetadata(this IPagedList pagedList, IHeaderDictionary header)
    {
        var paginationMetadata = new
        {
            currentPage = pagedList.CurrentPageIndex,
            totalCount = pagedList.TotalItemCount,
            pageSize = pagedList.PageSize,
            totalPages = pagedList.TotalPageCount,
            startItemIndex = pagedList.StartItemIndex,
            endItemIndex = pagedList.EndItemIndex
        };
        var json = JsonSerializer.Serialize(paginationMetadata);
        header.Append("X-Pagination", json);
    }

    /// <summary>
    /// 使用Response header中间件
    /// </summary>
    /// <param name="builder"></param>
    /// <returns></returns>
    public static IApplicationBuilder UseResponseHeaders(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<HttpResponseHeaderHandel>();
    }
    
    /// <summary>
    /// 请求记录中间件
    /// </summary>
    /// <param name="builder"></param>
    /// <returns></returns>
    public static IApplicationBuilder UseRequestRecord(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<HttpRequestRecord>();
    }

    /// <summary>
    /// 日期格式化中间件
    /// </summary>
    /// <param name="builder"></param>
    /// <returns></returns>
    public static IApplicationBuilder UseDateTimeLocalFormat(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<DateTimeFormattingMiddleware>();
    }

    /// <summary>
    /// 图像类型
    /// </summary>
    public static string[] PictureTypes =>
        typeof(PictureType)
            .GetFields()
            .Where(x => x.IsPublic && x.IsStatic)
            .Select(x => x.Name)
            .ToArray();

    /// <summary>
    /// 获取IP地址
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    public static string GetIpAddress(this HttpRequest request)
    {
        if (request == null)
            return "";
#if DEBUG
        return "113.110.235.52";
#endif
        var xff = request.Headers["X-Forwarded-For"];
        return string.IsNullOrEmpty(xff)
            ? request.HttpContext.Connection.RemoteIpAddress.ToString()
            : xff.ToString();
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="objectStorageService"></param>
    /// <param name="music"></param>
    /// <exception cref="ArgumentNullException"></exception>
    /// <exception cref="ArgumentException"></exception>
    public static async Task DeleteMusicAsync(
        this IObjectStorageOperation objectStorageService,
        VmMusic music
    )
    {
        if (music == null)
            throw new ArgumentNullException(nameof(music));
        if (string.IsNullOrEmpty(music.MusicUrl))
            throw new ArgumentException(
                "property MusicUrl is empty or null",
                nameof(music.MusicUrl)
            );

        await objectStorageService.DeleteAsync(music.MusicUrl);

        if (!string.IsNullOrEmpty(music.CoverUrl))
            await objectStorageService.DeleteAsync(music.CoverUrl);

        if (!string.IsNullOrEmpty(music.LyricUrl))
            await objectStorageService.DeleteAsync(music.LyricUrl);
    }

#nullable enable
    /// <summary>
    ///
    /// </summary>
    /// <param name="builder"></param>
    /// <param name="setup"></param>
    /// <returns></returns>
    public static IMvcBuilder AddMessagePackSerializerFormatters(
        this IMvcBuilder builder,
        Action<MessagePackFormatterOptions>? setup = null
    )
    {
        builder.Services.Configure<MessagePackFormatterOptions>(o =>
        {
            if (o.FormatterResolver == null)
                o.FormatterResolver = ContractlessStandardResolver.Instance;
            setup?.Invoke(o);
        });

        builder.Services.TryAddEnumerable(
            ServiceDescriptor.Transient<
                IConfigureOptions<MvcOptions>,
                MessagePackFormatterMvcOptionsSetup
            >()
        );
        return builder;
    }
#nullable restore
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

上述代码是一个 C# 类库的扩展方法集合,主要用于 ASP.NET Core Web API 项目中。以下是对代码中各个部分的详细解释:

1. GetIdentity 方法

  • 功能: 从 ClaimsPrincipal 对象中提取当前用户的信息,并将其映射到 VmUserInfo 对象。
  • 实现:
    • 检查用户是否经过身份验证。
    • 遍历用户的声明(Claims),根据声明的类型将值设置到 VmUserInfo 的相应属性中。
    • 支持的属性类型包括 DateTime?Sexbool?Permissions?

2. AddPaginationMetadata 方法

  • 功能: 为响应头添加分页元数据。
  • 实现:
    • 接收一个 IPagedList 对象和一个 IHeaderDictionary 对象。
    • 创建一个包含当前页、总项数、页大小、总页数等信息的对象,并将其序列化为 JSON 字符串。
    • 将 JSON 字符串添加到响应头中,键为 X-Pagination

3. 中间件扩展方法

  • UseResponseHeaders: 注册一个中间件,用于处理 HTTP 响应头。
  • UseRequestRecord: 注册一个中间件,用于记录 HTTP 请求。
  • UseDateTimeLocalFormat: 注册一个中间件,用于处理日期时间格式化。

4. PictureTypes 属性

  • 功能: 获取 PictureType 枚举中所有公共静态字段的名称,返回一个字符串数组。

5. GetIpAddress 方法

  • 功能: 从 HTTP 请求中获取客户端的 IP 地址。
  • 实现:
    • 在调试模式下返回一个固定的 IP 地址。
    • 检查请求头中的 X-Forwarded-For 字段,如果存在则返回该值,否则返回连接的远程 IP 地址。

6. DeleteMusicAsync 方法

  • 功能: 异步删除音乐及其相关资源(如封面和歌词)。
  • 实现:
    • 检查传入的 VmMusic 对象是否为 null,及其 MusicUrl 是否为空。
    • 调用 IObjectStorageOperation 接口的 DeleteAsync 方法删除音乐 URL、封面 URL 和歌词 URL。

7. AddMessagePackSerializerFormatters 方法

  • 功能: 为 MVC 构建器添加 MessagePack 序列化格式化程序。
  • 实现:
    • 配置 MessagePackFormatterOptions,如果未指定格式化程序解析器,则使用默认的 ContractlessStandardResolver
    • MessagePackFormatterMvcOptionsSetup 注册为服务。

总结

这个类库提供了一系列扩展方法,旨在简化 ASP.NET Core Web API 的开发,处理用户身份、分页、请求记录、IP 地址获取、资源删除和序列化等常见任务。通过这些扩展方法,开发人员可以更方便地实现功能,提高代码的可读性和可维护性。

loading