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

ASP.NET Core Web API控制器重复初始化及状态重置问题咨询

问题:Web API每次CRUD后数据恢复默认,控制器每次调用都重新初始化

我是Web API开发新手,目前遇到一个问题:每次执行CRUD调用后,数据都会恢复到默认状态,并且每次调用前控制器对象都会重新初始化。希望有人能指导问题原因。

代码展示

Program.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

PlayersController.cs

using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Unity_RestApi_Custom.Contracts;

namespace Unity_RestApi_Custom.Controllers
{
    [Route("api/[controller]")]
    public class PlayersController : Controller
    {
        int counter = 0;
        private static List<Player> players;

        public PlayersController(ILogger<PlayersController> logger)
        {
            //_logger = logger;
            players = new List<Player>();

            players.Add(new Player(1, "Name 1 Text", 1));
            players.Add(new Player(2, "Name 2 Text", 2));
            players.Add(new Player(3, "Name 3 Text", 3));
            System.Diagnostics.Debug.WriteLine("Testing Constructor");
        }

        /*
        [HttpGet(Name = "Players")]
        public IEnumerable<Player> Get()
        {
            Player player = players.Single(p => p.Id == id);
            return Enumerable.Range(0, players.Count).Select(index => new Player
            {
                Id = players[index].Id ,
                FullName = players[index].FullName,
                Score = players[index].Score
            })
            .ToArray();;
            yield return player;
        }*/

        [HttpGet]
        public JsonResult Get()
        {
            System.Diagnostics.Debug.WriteLine("Players Count == " + players.Count);
            return Json(players);
            //return new JsonResult(Random.Shared.Next());
        }

        [HttpGet("{id}")]
        public JsonResult Get(int id)
        {
            Player player = players.Single(p => p.Id == id);
            return Json(player);
        }

        [HttpPost]
        public JsonResult Post([FromBody] Player newPlayer)
        {
            players.Add(newPlayer);
            return Json(players);
        }

        [HttpPut("{id}")]
        public JsonResult Put(int id,[FromBody] int newScore)
        {
            /*Player player = players.Single(player => player.Id == id);
            player.Score = newScore;
            return Json(player);*/

            for (int i = 0; i < players.Count; i++)
            {
                if (players[i].Id == id)
                {
                    players[i].Score = newScore;
                }
            }

            return Json(players);
        }

        [HttpDelete("{id}")]
        public JsonResult Delete(int id)
        {
            List<Player> playersLocal = players;
            Player player = playersLocal.Single(player => player.Id == id);
            playersLocal.Remove(player);
            players = playersLocal;
            //System.Diagnostics.Debug.WriteLine("Players Count == "+ playersLocal.Count);
            return Json(players);
        }
    }
}

Player 模型类

using System;
using Newtonsoft.Json;

namespace Unity_RestApi_Custom.Contracts
{
    [JsonObject,Serializable]
    public class Player
    {
        public int Id { get; set; }
        public string FullName { get; set; }
        public int Score { get; set; }

        public Player(int Id,string FullName,int Score)
        {
            this.Id = Id;
            this.FullName = FullName;
            this.Score= Score;
        }
    }
}

问题原因分析

  1. 控制器生命周期特性:ASP.NET Core中,控制器默认是**瞬时(Transient)**生命周期,意味着每收到一个HTTP请求,都会创建一个全新的PlayersController实例。这就是你看到“每次调用前控制器对象重新初始化”的原因。

  2. static变量被重复初始化:虽然你把players声明为static,但在控制器的构造函数中,每次创建新控制器实例时都会执行players = new List<Player>()并添加默认数据,直接覆盖了之前通过CRUD操作修改的列表。这才是数据每次恢复默认的核心问题。

修复方案

方案1:修改static变量的初始化逻辑

把默认数据的初始化移到static变量声明处,或者只在players为空时才初始化,避免每次构造控制器都重置数据:

private static List<Player> players = new List<Player>
{
    new Player(1, "Name 1 Text", 1),
    new Player(2, "Name 2 Text", 2),
    new Player(3, "Name 3 Text", 3)
};

public PlayersController(ILogger<PlayersController> logger)
{
    // 移除原来的初始化代码,只保留日志相关(如果需要)
    // _logger = logger;
    System.Diagnostics.Debug.WriteLine("Testing Constructor");
}

或者用惰性初始化:

private static List<Player> players;

public PlayersController(ILogger<PlayersController> logger)
{
    if (players == null)
    {
        players = new List<Player>();
        players.Add(new Player(1, "Name 1 Text", 1));
        players.Add(new Player(2, "Name 2 Text", 2));
        players.Add(new Player(3, "Name 3 Text", 3));
    }
    System.Diagnostics.Debug.WriteLine("Testing Constructor");
}

方案2:使用单例服务存储数据(更规范)

对于测试或小型应用,推荐创建一个单例服务来管理数据,替代控制器中的static变量:

  1. 创建数据服务接口和实现:
public interface IPlayerService
{
    List<Player> GetAllPlayers();
    Player GetPlayerById(int id);
    void AddPlayer(Player player);
    void UpdatePlayerScore(int id, int newScore);
    void DeletePlayer(int id);
}

public class PlayerService : IPlayerService
{
    private List<Player> _players;

    public PlayerService()
    {
        _players = new List<Player>
        {
            new Player(1, "Name 1 Text", 1),
            new Player(2, "Name 2 Text", 2),
            new Player(3, "Name 3 Text", 3)
        };
    }

    // 实现接口中的方法...
    public List<Player> GetAllPlayers() => _players;
    public Player GetPlayerById(int id) => _players.Single(p => p.Id == id);
    public void AddPlayer(Player player) => _players.Add(player);
    public void UpdatePlayerScore(int id, int newScore)
    {
        var player = _players.Single(p => p.Id == id);
        player.Score = newScore;
    }
    public void DeletePlayer(int id)
    {
        var player = _players.Single(p => p.Id == id);
        _players.Remove(player);
    }
}
  1. 在Program.cs中注册单例服务:
builder.Services.AddSingleton<IPlayerService, PlayerService>();
  1. 修改控制器,通过依赖注入使用服务:
private readonly IPlayerService _playerService;

public PlayersController(ILogger<PlayersController> logger, IPlayerService playerService)
{
    // _logger = logger;
    _playerService = playerService;
    System.Diagnostics.Debug.WriteLine("Testing Constructor");
}

[HttpGet]
public JsonResult Get()
{
    return Json(_playerService.GetAllPlayers());
}

// 其他CRUD方法也改为调用_playerService的对应方法...

注意:以上两种方案都是基于内存存储,应用重启后数据会丢失。生产环境需要使用数据库(如SQL Server、SQLite等)来持久化数据。

内容的提问来源于stack exchange,提问作者Learners Tube

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 06:37:29