ASP.NET Core Web API:控制器重新初始化问题。

huangapple go评论53阅读模式
英文:

ASP.NET Core Web API : controller reinitialization problem,

问题

请帮我解释为什么每次进行 CRUD 调用后我只能更新默认状态,并且为什么在每次调用之前控制器对象都会重新初始化。

这是我的代码:

Program.cs

var builder = WebApplication.CreateBuilder(args);

// 将服务添加到容器中。

builder.Services.AddControllers();
// 了解有关配置 Swagger/OpenAPI 的更多信息,请访问 https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// 配置 HTTP 请求管道。
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

PlayerController

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]
        public JsonResult Get()
        {
            System.Diagnostics.Debug.WriteLine("Players Count == " + players.Count);
            return Json(players);
        }

        [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)
        {
            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;
            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;
        }
    }
}

基本上,我是 Web API 开发的新手,因此不知道该何去何从。

英文:

Can anyone guide me why I am only able to update the default state after every crud call and why the controller object is reinitialized every time before the call.

Here is my code:

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();

PlayerController:

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

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

        public PlayersController(ILogger&lt;PlayersController&gt; logger)
        {
            //_logger = logger;
            players = new List&lt;Player&gt;();

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

        /*
        [HttpGet(Name = &quot;Players&quot;)]
        public IEnumerable&lt;Player&gt; Get()
        {
            Player player = players.Single(p =&gt; p.Id == id);
            return Enumerable.Range(0, players.Count).Select(index =&gt; 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(&quot;Players Count == &quot; + players.Count);
            return Json(players);
            //return new JsonResult(Random.Shared.Next());
        }

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

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

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

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

            return Json(players);
        }

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

and Player model class:

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;
        }
    }
}

Basically I am a newbie to Web API development therefore I don't know which direction to go.

答案1

得分: 0

你遇到这个问题的原因是你在控制器的构造函数中创建了玩家列表。

控制器是一个作用域资源,它们在每个请求时创建和销毁,因此每次都会调用构造函数,这会破坏你的静态列表的状态。

要解决这个问题,将玩家列表的创建移到内联实例化器中,或者移到控制器的静态构造函数中(注意,使用静态构造函数不能保证解决问题,但它更接近你的意图)。

int counter = 0;
private static List<Player> players = new List<Player>(new[] {
    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");
}
英文:

The reason you have this issue is that you are creating the players list in the constructor of your controller.

The controller is a scoped resource, they are created and destroyed for every request, so each time, the constructor is called and it destroys the state of your static list.

To fix this, move the creation of your player list into an inline instatiator, or the static constructor of the controller (nb. using the static constructor is no guarantee, but it is closer to your intent)

        int counter = 0;
        private static List&lt;Player&gt; players = new List&lt;Player&gt;(new[] {
            new Player(1, &quot;Name 1 Text&quot;, 1),
            new Player(2, &quot;Name 2 Text&quot;, 2),
            new Player(3, &quot;Name 3 Text&quot;, 3)
        };

        public PlayersController(ILogger&lt;PlayersController&gt; logger)
        {
            //_logger = logger;
            System.Diagnostics.Debug.WriteLine(&quot;Testing Constructor&quot;);
        }

huangapple
  • 本文由 发表于 2023年5月22日 04:55:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76301891.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定