为 14 个项目中缺少 XML 注释的类、接口、方法、属性、字段、record、 枚举等成员补全中文文档注释。接口方法在接口层定义完整注释,实现类 使用 <inheritdoc /> 引用。私有辅助方法结合业务语义编写注释。 扫描结果:missing-csharp-docs.txt 缺失项归零。 构建结果:0 警告,0 错误。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
62 lines
2.4 KiB
C#
62 lines
2.4 KiB
C#
using System.Text.Json;
|
||
using System.Text.Json.Serialization;
|
||
|
||
namespace FileShare_Services.Core
|
||
{
|
||
/// <summary>
|
||
/// Binds unified endpoint request models from JSON bodies or query parameters.
|
||
/// </summary>
|
||
internal static class ServiceRequestBinder
|
||
{
|
||
private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web)
|
||
{
|
||
NumberHandling = JsonNumberHandling.AllowReadingFromString,
|
||
};
|
||
|
||
/// <summary>
|
||
/// Bind a JSON request body. Empty bodies are treated as an empty JSON object.
|
||
/// </summary>
|
||
public static T BindBody<T>(ServiceEndpointContext context)
|
||
{
|
||
var json = string.IsNullOrWhiteSpace(context.Body) ? "{}" : context.Body;
|
||
return Deserialize<T>(json, "body");
|
||
}
|
||
|
||
/// <summary>
|
||
/// Bind route and query parameters to a request DTO.
|
||
/// </summary>
|
||
public static T BindQuery<T>(ServiceEndpointContext context)
|
||
{
|
||
var values = new Dictionary<string, string>(context.Query, StringComparer.OrdinalIgnoreCase);
|
||
foreach (var routeValue in context.RouteValues)
|
||
{
|
||
values[routeValue.Key] = routeValue.Value;
|
||
}
|
||
|
||
var json = JsonSerializer.Serialize(values, JsonOptions);
|
||
return Deserialize<T>(json, "query");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将 JSON 反序列化为目标类型,反序列化失败或结果为 null 时抛出 <see cref="ArgumentException"/>。
|
||
/// </summary>
|
||
/// <typeparam name="T">目标类型。</typeparam>
|
||
/// <param name="json">JSON 字符串。</param>
|
||
/// <param name="source">来源标识(body 或 query),用于异常消息。</param>
|
||
/// <returns>反序列化后的实例。</returns>
|
||
/// <exception cref="ArgumentException">JSON 无法绑定到目标类型时抛出。</exception>
|
||
private static T Deserialize<T>(string json, string source)
|
||
{
|
||
try
|
||
{
|
||
return JsonSerializer.Deserialize<T>(json, JsonOptions)
|
||
?? throw new ArgumentException($"Request {source} cannot be bound to {typeof(T).Name}.");
|
||
}
|
||
catch (JsonException ex)
|
||
{
|
||
throw new ArgumentException($"Request {source} cannot be bound to {typeof(T).Name}.", ex);
|
||
}
|
||
}
|
||
}
|
||
}
|