网站首页 网站源码
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
}
上述代码是一个 C# 类库的扩展方法集合,主要用于 ASP.NET Core Web API 项目中。以下是对代码中各个部分的详细解释:
GetIdentity
方法ClaimsPrincipal
对象中提取当前用户的信息,并将其映射到 VmUserInfo
对象。VmUserInfo
的相应属性中。DateTime?
、Sex
、bool?
和 Permissions?
。AddPaginationMetadata
方法IPagedList
对象和一个 IHeaderDictionary
对象。X-Pagination
。UseResponseHeaders
: 注册一个中间件,用于处理 HTTP 响应头。UseRequestRecord
: 注册一个中间件,用于记录 HTTP 请求。UseDateTimeLocalFormat
: 注册一个中间件,用于处理日期时间格式化。PictureTypes
属性PictureType
枚举中所有公共静态字段的名称,返回一个字符串数组。GetIpAddress
方法X-Forwarded-For
字段,如果存在则返回该值,否则返回连接的远程 IP 地址。DeleteMusicAsync
方法VmMusic
对象是否为 null,及其 MusicUrl
是否为空。IObjectStorageOperation
接口的 DeleteAsync
方法删除音乐 URL、封面 URL 和歌词 URL。AddMessagePackSerializerFormatters
方法MessagePackFormatterOptions
,如果未指定格式化程序解析器,则使用默认的 ContractlessStandardResolver
。MessagePackFormatterMvcOptionsSetup
注册为服务。这个类库提供了一系列扩展方法,旨在简化 ASP.NET Core Web API 的开发,处理用户身份、分页、请求记录、IP 地址获取、资源删除和序列化等常见任务。通过这些扩展方法,开发人员可以更方便地实现功能,提高代码的可读性和可维护性。