You need to enable JavaScript to run this app. C#后端基于dayOfAttendance动态生成指定结构JSON响应的实现
优惠活动
大模型
产品
解决方案
定价
更多

C#后端基于dayOfAttendance动态生成指定结构JSON响应的实现

核心问题定位
  • 嵌套层级冗余:当前定义的EmployeeAttendance类是普通实体类,内部嵌套了KeyValuePairsAttendance字典属性,序列化后会在employeeAttendance节点下多出一层KeyValuePairsAttendance属性名,完全偏离目标结构中“employeeAttendance本身就是以出勤日为键的动态对象”的要求
  • 实体类字段缺失:现有Att类遗漏了目标结构里的id、qrCodeId两个必填字段,导致序列化结果缺字段
  • 键值映射逻辑错位:没有直接把dayOfAttendance的字符串值作为employeeAttendance对象的根级键,而是把值存在了字典的value对象内部
修正实现步骤

1. 调整类结构匹配目标层级

直接删除冗余的EmployeeAttendance实体类,将EmployeeAttendanceModel中EmployeeAttendance属性的类型改为键为字符串、值为考勤实体的字典类型,从根源上消除多余嵌套层。同时补全Att类缺失的字段。

2. 配置序列化规则匹配JSON格式

不管使用System.Text.Json还是Newtonsoft.Json作为序列化组件,都需要开启小驼峰属性命名策略,让C#中PascalCase格式的属性名自动转换为目标JSON要求的小驼峰格式(比如EmployeeName自动转employeeName)。枚举类型默认序列化输出整数值,刚好匹配目标中attendanceStatus的整数格式,无需额外处理。

3. 数据填充逻辑调整

遍历所有考勤记录,将每条记录的dayOfAttendance值转为字符串作为字典的键,对应的考勤实体作为值存入字典,保证键不重复。

修正后的完整代码示例
using System.Collections.Generic;

namespace abc
{
    // 通用顶层响应实体
    public class ApiResponse<T>
    {
        public bool Success { get; set; }
        public int Code { get; set; }
        public T[] Data { get; set; }
    }

    // 员工维度的考勤响应实体
    public class EmployeeAttendanceModel
    {
        public string EmployeeName { get; set; }
        // 直接将属性类型替换为字典,消除之前的冗余嵌套层
        public Dictionary<string, Att> EmployeeAttendance { get; set; }
    }

    // 单条考勤记录实体
    public class Att 
    {
        public int Id { get; set; } // 补全缺失的id字段
        public DateTime CheckInTime { get; set; }
        public int LateDuration { get; set; }
        public string EmployeeName { get; set; }
        public long EmployeeDeviceID { get; set; }
        public string QrCodeId { get; set; } // 补全缺失的qrCodeId字段
        public int DayOfAttendance { get; set; }
        public AttendanceStatus AttendanceStatus { get; set; }
    }

    public enum AttendanceStatus
    {
        Normal = 0,
        Late = 1
    }
}
数据填充与序列化示例
// 模拟从数据库取出的员工考勤列表
var employeeName = "Zaigham";
var attendanceList = new List<Att>
{
    new Att {
        Id = 2,
        CheckInTime = new DateTime(2021,3,3,16,48,10),
        LateDuration = 10,
        EmployeeName = employeeName,
        EmployeeDeviceID = 2,
        QrCodeId = "QRCodeID",
        DayOfAttendance = 3,
        AttendanceStatus = AttendanceStatus.Normal
    },
    // 其他考勤记录依次添加...
};

// 按dayOfAttendance构建字典,字符串形式的日期作为键
var attendanceDict = attendanceList
    .GroupBy(item => item.DayOfAttendance.ToString())
    .ToDictionary(
        keySelector: group => group.Key,
        elementSelector: group => group.First()
    );

// 组装最终响应
var response = new ApiResponse<EmployeeAttendanceModel>
{
    Success = true,
    Code = 200,
    Data = new[]
    {
        new EmployeeAttendanceModel
        {
            EmployeeName = employeeName,
            EmployeeAttendance = attendanceDict
        }
    }
};

// 配置.NET内置System.Text.Json序列化规则
var jsonOptions = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    WriteIndented = true
    // 框架默认将枚举序列化为整数,匹配目标结构要求
};
var resultJson = JsonSerializer.Serialize(response, jsonOptions);

// 若使用Newtonsoft.Json,对应序列化配置为:
// var settings = new JsonSerializerSettings
// {
//     ContractResolver = new CamelCasePropertyNamesContractResolver(),
//     Formatting = Formatting.Indented
// };
// var resultJson = JsonConvert.SerializeObject(response, settings);
效果验证

执行上述代码生成的JSON结构将完全匹配目标要求,不会再出现多余的KeyValuePairsAttendance嵌套层,employeeAttendance对象下直接以"1"、"3"、"15"这类天数值作为动态键,字段名称、类型完全对齐。

内容的提问来源于stack exchange,提问作者Zaigham Raza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.01 01:45:02