我在Asp.Net Core世界中是个新手,现在我正在使用服务。我有一个想法来创建自己创建的类的实例(名为 CourseEditor ),该实例可以通过整个控制器(在该控制器上的所有操作)进行访问。因此,我将该类作为范围服务添加到 Startup.cs 和方法 ConfigureServices :
services.AddScoped<CourseEditor>();
现在我有了我的控制器 CourseEditorController.cs 。
[Authorize(Roles = "Admin")]
[ViewLayout("_CourseEditorLayout")]
public class CourseEditorController : Controller
{
private CourseEditor _courseEditor;
private readonly SignInManager<IdentityUser> _signInManager;
public CourseEditorController(SignInManager<IdentityUser> signInManager, CourseEditor courseEditor)
{
_courseEditor = courseEditor;
_signInManager = signInManager;
}
[HttpGet]
public async Task<IActionResult> OpenCourse(int courseId)
{
Database db = new Database();
_courseEditor = await db.LoadCourseForEditByIDAsync(courseId);
return RedirectToAction("Index");
}
public IActionResult Index()
{
return View(_courseEditor);
}
public IActionResult EditHead()
{
return View(_courseEditor);
}
}
我很困。因为每次我加载到该控制器中,_courseEditor
都会被重写为默认值。因此,现在我试图弄清楚如何更改服务CourseEditor
本身的参数,以免每次我在操作之间跳转时都不会“重置” _courseEditor
。
所以基本上,我试图在控制器 CourseEditorController.cs 中更改服务CourseEditor.Title
,因为默认情况下它是null
,并且它是从实际文本中重写_courseEditor.Title
到null
。我可以这样做吗?
//编辑:
我忘了解释控制器的工作原理。因此,基本上,当用户移动到此“编辑器”控制器时,首先它将执行操作“ OpenCourse”,该操作将以_courseEditor.Title
的形式加载所有数据,并从MySQL数据库中加载内容。但是正如您所看到的,在那之后有一个RedirectToAction("Index")
。因此,_courseEditor
是通过构造函数运行的,并且所有内容都被重置回null
,因为它是程序初始化服务时设置的值。或者至少我认为这正在发生。
答案 0 :(得分:0)
因此,解决方案是不将服务添加为范围服务,而是添加为Singleton。
services.AddSingleton<CourseEditor>();
对我来说不幸的是,这并不能解决任何问题,因为Singleton代表整个应用程序的一个实例,这意味着每个用户都可以从该编辑器实例中看到数据。他们无法创建自己的编辑器实例。
一种实现创建更多实例的可能性的方法是通过 ConcurrentDictionary (感谢@Legacy代码进行解释)。有关此静态词典的更多详细信息,请参见Asp.net核心文档: https://docs.microsoft.com/cs-cz/dotnet/api/system.collections.concurrent.concurrentdictionary-2?view=netcore-3.1
第二种方法可能是在每次Action调用时仅从数据库中恢复数据。
另一种方法可能是使用某种运输工具作为Cookies,但是这种方法不是很安全,因为用户可以使用Cookies进行操作,并且实际上很难在其中存储复杂的对象。