关于静态变量如何在ASP.NET中工作的简单问题?

时间:2009-07-14 16:22:59

标签: c# asp.net

我有一张显示一些信息的地图。默认情况下,地图上的标签已关闭。有一个图像按钮,当标签关闭时,该图像按钮具有与其关联的关闭图像,当您打开标签时,该图像按钮具有与其关联的打开图像。我有代码工作,但我想要一个更好的理由,为什么它以这种方式工作。这是一段代码。

如果我声明一个类级别的布尔变量showLabels,如:

private bool showLabels = false;

然后有以下代码:

if(showLabels == false)
{
    showLabels = true;
    imgShowLabels.ImageUrl = "label-on.png";
}
else
{
    showLabels = false;
    imgShowLabels.ImageUrl = "label-off.png";
}

当我运行它时,地图会显示默认情况下未显示的标签。当我单击Show Labels按钮时,变量showLabels变为true并且图像变为label-on.png,但是当我再次单击它时,showLabels变量将重置为false,因此没有任何反应。

所以我所做的就是改变它:

private bool showLabels = false;

private static bool showLabels = false;

它正在以这种方式工作。

这是处理此类情况的正确方法吗?

在课程级别,我把属性:

public bool ShowLabels
{
    get { return (bool)ViewState["ShowLabels"]; }
    set { ViewState["ShowLabels"] = value; }
}

在if(!Page.IsPostBack)中,我将ShowLabels设置为false;

然后在我的if语句中,我正在做:

if(ShowLabels == false)
{
    ShowLabels = true;
    imgShowLabels.ImageUrl = "label-on.png";
}
else
{
    ShowLabels = false;
    imgShowLabels.ImageUrl = "label-off.png";
}

但是ShowLabels总是假的,我认为通过ShowLabels属性设置ViewState,它会保留它的值。

4 个答案:

答案 0 :(得分:8)

请记住,每次您进行回发(出于任何原因,包括仅处理服务器事件),您都在使用页面类的全新实例。旧的一个已经死了 - 一旦页面最后一次呈现给浏览器就有资格使用。

当您将其更改为静态时它“有效”,因为静态变量与任何特定实例都没有关联。但是,我怀疑当你在更广阔的环境中开始测试时,你会感到惊讶。由于该网站页面的所有用户都在同一个AppDomain中,因此他们都将设置相同的 showLabels变量。

要解决此问题,您需要将此变量存储在仅为该用户持久存在的位置。选项包括ViewState,Session,数据库或其他一些长期存储机制。我的偏好倾向于数据库(可能使用带有sql server的ASP.Net Personalization提供程序),因为用户可能希望您每次访问您的站点时都记住这一点。


如何'回合:

ShowLabels = !ShowLabels;
imgShowLabels.ImageUrl = string.Format("label-{0}.png", (ShowLabels)?"on":"off");

答案 1 :(得分:2)

乔尔击中头部,但我想补充一点,你应该做的就是将功能放在客户端上,以确保你的静态变量不会被意外清理。

我会做类似的事情:

<a href="[YourPageHere.aspx]?showLabel=[togglethisvalue]>Show Labels</a>

对于Webforms。然后,您可以将其作为查询变量进行处理。通过这种方式,您可以获得正确的价值。在客户端有很多其他方法可以做到这一点。我使用查询变量方法是为了简化,但这可能无法使您的页面变得更健壮。

答案 2 :(得分:1)

不确定ASP,但作为一种风格的东西,有

if(showLabels == false)

不太可读。你应该使用

if(!showLabels)

代替

答案 3 :(得分:1)

不,因为这是一个多线程多用户应用程序,因为所有Web应用程序通常都是如此。如果将变量设置为静态,则实际上在为站点上的每个用户启用标签时,您都打开了标签。

由于您说这是ASP.NET,您可能希望将其存储在ViewState中。您可以通过以下方式执行此操作:

ViewState["ShowLabels"] = false;

你可以将它包装在一个属性中。

public bool ShowLabels { 
    get { return (bool)ViewState["ShowLabels"]; }
    set { ViewState["ShowLabels"] = value; }
}

希望这会有所帮助。 ViewState的替代方法是SessionState,您可以使用相同的构造。

public bool ShowLabels { 
    get { return (bool)Session["ShowLabels"]; }
    set { Session["ShowLabels"] = value; }
}