You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET Web API中读写现有JSON文件并实现POST新增数据

ASP.NET Web API 操作JSON文件:读取优化与POST新增实现

一、优化现有JSON读取逻辑

原代码使用已过时的WebClient读取本地文件,推荐更高效的本地文件读取方式,同时优化API返回格式:

优化后的读取代码

[Route("api/[controller]")]
[ApiController]
public class StudentsController : ControllerBase
{
    // 建议将文件路径配置到appsettings.json,示例暂时用绝对路径
    private readonly string _jsonFilePath = "C:/Users/tanmay_pawar/source/repos/CRUDAPI/CRUDAPI/output.json";

    [HttpGet("JSONFile")]
    public IActionResult GetStudents()
    {
        // 直接读取本地文件,性能更优
        var jsonContent = System.IO.File.ReadAllText(_jsonFilePath);
        // 注意:需确保实体类与JSON结构匹配,见下文实体类修正说明
        var studentRoot = JsonConvert.DeserializeObject<Students>(jsonContent);
        // 直接返回学生列表,更符合API设计习惯
        return Ok(studentRoot?.students ?? new List<Student>());
    }
}

实体类修正(关键)

原JSON中根节点的键是"Students"(大写S),但实体类Students的属性是小写students,会导致反序列化失败,需添加JsonProperty特性匹配:

public class Student
{
    // 匹配JSON中的小写"id"
    [JsonProperty("id")]
    public int Id { get; set; }
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("department")]
    public string Department { get; set; }
}

public class Students
{
    [JsonProperty("Students")]
    public List<Student> students { get; set; }
}

或者遵循C#命名规范修改实体类,同时保持与JSON结构兼容:

public class StudentRoot
{
    public List<Student> Students { get; set; }
}

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Department { get; set; }
}

二、实现POST方法新增学生数据

以下是完整的新增逻辑,包含数据验证、ID生成、文件写入:

[HttpPost("AddStudent")]
public IActionResult AddStudent([FromBody] Student newStudent)
{
    // 验证传入的学生数据合法性
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    // 读取现有JSON数据,若文件为空则初始化空列表
    var jsonContent = System.IO.File.ReadAllText(_jsonFilePath);
    var studentRoot = JsonConvert.DeserializeObject<Students>(jsonContent) 
        ?? new Students { students = new List<Student>() };

    // 生成唯一ID:取现有最大ID+1,确保不重复
    int newId = studentRoot.students.Any() 
        ? studentRoot.students.Max(s => s.Id) + 1 
        : 1;
    newStudent.Id = newId;

    // 添加新学生到列表
    studentRoot.students.Add(newStudent);

    // 将更新后的数据写回JSON文件,格式化输出便于查看
    var updatedJson = JsonConvert.SerializeObject(studentRoot, Formatting.Indented);
    System.IO.File.WriteAllText(_jsonFilePath, updatedJson);

    // 返回符合REST规范的响应:201 Created,附带新资源信息
    return CreatedAtAction(nameof(GetStudents), new { id = newStudent.Id }, newStudent);
}

三、核心注意事项

  • 并发问题:File.WriteAllText是原子操作,但高并发场景下仍可能出现文件冲突,生产环境建议改用数据库或添加文件锁机制。
  • 路径配置:不要硬编码文件路径,推荐将路径存入appsettings.json,通过IConfiguration读取,提升代码可维护性。
  • 模型验证:依赖[ApiController]特性自动触发模型验证,确保传入数据符合要求。

内容的提问来源于stack exchange,提问作者Tanmay Pawar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 10:16:04