如何在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
相关产品推荐
相关产品推荐

