如何在 MVC3 中的不同操作方法调用之间保持全局变量的值
本文关键字:之间 调用 全局变量 操作方法 MVC3 | 更新日期: 2023-09-27 17:56:07
我正在使用Razor和C#开发一个 ASP.NET MVC 3 Web应用程序。
我刚刚发现我在全局变量方面有一些问题,可能是因为我对 MVC 比较陌生。
我有一个带有一些全局变量和操作方法的控制器。我声明了一个全局变量,以便允许操作方法操作它并将操作反映到所有操作方法。我有以下情况:
public class myController : Controller
{
private string _MyGlobalVariable;
public ActionResult Index()
{
_MyGlobalVariable = "Hello";
//other code
return View("MyView");
}
public ActionResult Print()
{
_MyGlobalVariable += "Print";
return View("PrintView", _MyGlobalVariable);
}
}
Print() 操作方法是使用 MyView 视图中的 Html.ActionLink() 调用的。
令人惊讶的是,_MyGlobalVariable的价值并没有保留!因此,指令_MyGlobalVariable += "Print"
之前的_MyGlobalVariable值等于 null。
我是不是搞错了什么?如何在调用视图之间保留全局变量的值?
谢谢
弗朗切斯科
PS:在我的特定情况下,全局变量是一个Dictionary<K,V>
但我想它不会改变逻辑。
PPS:我知道您可以使用 ViewModels 而不是全局变量在操作方法之间传递数据,但就我而言,如果我使用通常不包装在 ViewModels 中的Dictionary<K,V>
,代码就会少得多(我使用 POCO 或 Lists<T>
)
每个请求都会获得一个新的控制器实例。
由于您的"变量"是一个实例字段,因此它不会持久化。
可以通过将其设为static
或使用应用程序状态来解决此问题。
但是,不要。
切勿在 Web 应用程序中使用可变全局状态。
特别是,如果您同时收到两个请求,您的字段将变得混乱。
根据您要执行的操作,您可能需要使用会话状态或 Cookie。
首先,C# 中没有全局变量这样的东西。你要找的是一个静态变量,可以通过类本身访问它。由于在每个请求上都会创建一个新的控制器实例,因此变量的值将丢失。
您需要这样声明变量:
private static string _MyGlobalVariable = "insert default value here";
并按以下方式访问它:
MyControllerClass._MyGlobalVariable
此外,此变量只能从 myController 类的方法访问,因为您已将其声明为 private。
除此之外,您可能希望在使用变量时锁定变量,因为最终会遇到竞争条件。
注意:我不建议这样做
您可以使用 TempData 字典来保存一步调用控制器。TempData 将数据发送到下一个会话 如果要将数据保留到所有会话,则应在所需的每个方法控制器中初始化该 TempData。
public ActionResult Index()
{
if (TempData["MyGlobalVariable"] == null)
return RedirectToAction("MyGlobalVariableInitializer");
else
TempData["MyGlobalVariable"] =(string)TempData["MyGlobalVariable"]+" world";
.
.
.
}
在 MyGlobalVariableInitializer 中,首次初始化 MyGlobalVariable。
public ActionResult CompanySelection()
{
return View();
}
public ActionResult MyGlobalVariableInitializer()
{
TempData["MyGlobalVariable"] = "Hello";
return RedirectToAction("Index");
}
正如大家所说,这里的全局变量是行不通的。 即使它们是一个好主意,它们也不会在 Web 场方案中工作,因为值仅在一台计算机上。
索引控制器操作可能如下所示。
public ActionResult Index()
{
myModel myStronglyTypedModel = new myModel();
myStronglyTypedModel.SomeStateIWantToKeep = "Hello";
return View(myStronglyTypedModel);
}
然后在你的打印中会这样做
public ActionResult Print(myModel myStronglyTypedModel)
{
myStronglyTypedModel.SomeStateIWantToKeep += "Print";
return View("PrintView");
}
你的观点可以从
@ModelType myModel
因此,您的视图将被强类型化。
我是一个 vb 人,所以有人可以随时纠正我的 c#。 我怀疑 vb 中的 @ModelType 指令在 c# 中@model但尚未检查。
干杯
您可能应该为此使用 ViewData 或使用 HttpContext。ViewData 仅对您当前的请求有效,因此通常比直接使用会话对象更好,因为您的数据将被删除,并且在下一个请求中不可用。使用会话对象可能会遇到多请求重叠问题。