fix: 修复后端 JSON 反序列化与循环引用问题
- Program.cs 添加 JsonStringEnumConverter + CamelCase 策略, 修复枚举值和 decimal 反序列化失败 - CreateHealthRecordRequest 改为 class + init 属性, 修复 decimal? 在位置记录中的 JSON 反序列化异常 - 运动计划 /current 端点改用匿名对象投影, 修复 EF Core 导航属性循环引用导致 JSON 无限递归
This commit is contained in:
@@ -122,6 +122,13 @@ public static class HealthEndpoints
|
|||||||
Guid.TryParse(http.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value, out var id) ? id : Guid.Empty;
|
Guid.TryParse(http.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value, out var id) ? id : Guid.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed record CreateHealthRecordRequest(
|
public sealed class CreateHealthRecordRequest
|
||||||
HealthMetricType Type, int? Systolic, int? Diastolic, decimal? Value,
|
{
|
||||||
string? Unit, HealthRecordSource Source, DateTime? RecordedAt);
|
public HealthMetricType Type { get; init; }
|
||||||
|
public int? Systolic { get; init; }
|
||||||
|
public int? Diastolic { get; init; }
|
||||||
|
public decimal? Value { get; init; }
|
||||||
|
public string? Unit { get; init; }
|
||||||
|
public HealthRecordSource Source { get; init; }
|
||||||
|
public DateTime? RecordedAt { get; init; }
|
||||||
|
}
|
||||||
|
|||||||
@@ -193,7 +193,21 @@ public static class RemainingEndpoints
|
|||||||
var today = DateOnly.FromDateTime(DateTime.Now);
|
var today = DateOnly.FromDateTime(DateTime.Now);
|
||||||
var monday = today.AddDays(-(int)today.DayOfWeek + 1);
|
var monday = today.AddDays(-(int)today.DayOfWeek + 1);
|
||||||
var plan = await db.ExercisePlans.Include(p => p.Items).FirstOrDefaultAsync(p => p.UserId == userId && p.WeekStartDate == monday);
|
var plan = await db.ExercisePlans.Include(p => p.Items).FirstOrDefaultAsync(p => p.UserId == userId && p.WeekStartDate == monday);
|
||||||
return Results.Ok(new { code = 0, data = plan, message = (string?)null });
|
if (plan == null) return Results.Ok(new { code = 0, data = (object?)null, message = (string?)null });
|
||||||
|
return Results.Ok(new
|
||||||
|
{
|
||||||
|
code = 0,
|
||||||
|
data = new
|
||||||
|
{
|
||||||
|
plan.Id, plan.WeekStartDate, plan.CreatedAt, plan.UpdatedAt,
|
||||||
|
items = plan.Items.Select(i => new
|
||||||
|
{
|
||||||
|
i.Id, i.DayOfWeek, i.ExerciseType, i.DurationMinutes,
|
||||||
|
i.IsCompleted, i.CompletedAt, i.IsRestDay
|
||||||
|
})
|
||||||
|
},
|
||||||
|
message = (string?)null
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group.MapPost("/", async (CreateExercisePlanRequest req, HttpContext http, AppDbContext db, CancellationToken ct) =>
|
group.MapPost("/", async (CreateExercisePlanRequest req, HttpContext http, AppDbContext db, CancellationToken ct) =>
|
||||||
|
|||||||
@@ -27,6 +27,14 @@ if (File.Exists(envPath))
|
|||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
// ---- JSON 配置(枚举字符串、camelCase)----
|
||||||
|
builder.Services.ConfigureHttpJsonOptions(options =>
|
||||||
|
{
|
||||||
|
options.SerializerOptions.Converters.Add(new System.Text.Json.Serialization.JsonStringEnumConverter());
|
||||||
|
options.SerializerOptions.PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase;
|
||||||
|
options.SerializerOptions.PropertyNameCaseInsensitive = true;
|
||||||
|
});
|
||||||
|
|
||||||
// ---- 数据库 ----
|
// ---- 数据库 ----
|
||||||
builder.Services.AddDbContext<AppDbContext>(options =>
|
builder.Services.AddDbContext<AppDbContext>(options =>
|
||||||
options.UseNpgsql(builder.Configuration.GetConnectionString("Default") ?? builder.Configuration["DB_CONNECTION"] ?? "Host=localhost;Database=health_manager;Username=postgres;Password=postgres"));
|
options.UseNpgsql(builder.Configuration.GetConnectionString("Default") ?? builder.Configuration["DB_CONNECTION"] ?? "Host=localhost;Database=health_manager;Username=postgres;Password=postgres"));
|
||||||
|
|||||||
Reference in New Issue
Block a user