设置变量的位置,以便它们在回发时不为空?

时间:2015-11-02 06:01:56

标签: c# asp.net webforms postback

我的网页允许用户从可用工具列表中选择一个或多个工具(通过从“可用”列表拖动到“选定”列表)。每当两个列表发生更改时,就会更新HiddenTools隐藏字段 - <li>列表中的ToolsActive存储为HiddenTools中逗号分隔的ID列表。当用户单击“保存”时,HiddenTools中的值将存储在数据库中。

aspx页面:

<asp:HiddenField runat="server" ID="HiddenTools"/>

/*<li> can be dragged from one list to the other. Every time the lists 
change, HiddenTools gets updated with the contents of ToolsSelected  
list, formatted as a comma separated string */

<ul id="ToolsAvailable">            
    <%foreach (KeyValuePair<int,string> tool in unusedTools){ %>
        <li id='<%= tool.Key %>'> <%= tool.Value %> </li>
    <% } %>
</ul>

<ul id="ToolsActive">
     <%foreach (KeyValuePair<int,string> aTool in selectedTools){ %>
         <li id='<%= aTool.Key %>'> <%= tool.Value %> </li>
     <% } %>
 </ul>

<asp:Button ID="btnSave" OnClick="btnSave_Click" runat="server" Text="Save"/>

代码隐藏:

public partial class Settings
{
    protected ToolPreferences prefs;

    protected Dictionary<int, string> tools;
    protected Dictionary<int, string> unusedTools;
    protected Dictionary<int, string> selectedTools;

    protected void Page_Load(object sender, EventArgs e)
    {
         int AccountId = getAccountId();
         if(!Page.IsPostBack){
             prefs = new ToolPreferences(AccountId);
             PopulateTools();
         }
    }

    private void PopulateTools()
    {
        tools = getPossibleTools();
        unusedTools = new Dictionary<int, string>();
        selectedTools = new Dictionary<int, string>();

        List<int> selectedList = new List<int>();
        if (!string.IsNullOrEmpty(prefs.Tools))
        {
            selectedList = prefs.Tools.Split(',').Select(int.Parse).ToList();
        }
        foreach (KeyValuePair<int, string> aTool in tools)
        {
            if (selectedList.Contains(aTool.Key))
            {
                selectedTools.Add(aTool.Key, aTool.Value);
            }
            else
            {
                unusedTools.Add(aTool.Key, aTool.Value);
            }
        }
    }

    protected void btnSavePreferences_Click(object sender, EventArgs e)
    {
        ToolPreferences tp = ToolPreferences (AccountId);
        tp.Update(HiddenTools.Value);
    }        

}

问题是在PostBack之后,出现以下错误:

  

未将对象引用设置为对象的实例。

突出显示以下行:

  

<%foreach (KeyValuePair<int,string> tool in unusedTools){ %>

如果我从!PageIsPostBack检查中移出以下两行,我在回发后重新加载页面时不会出现该错误,但我也看不到用户对工具列表所做的更改直到页面再次重新加载。

prefs = new ToolPreferences(AccountId);
PopulateTools();

在哪里可以设置工具变量,以便不会出现“未引用对象引用”错误?

1 个答案:

答案 0 :(得分:1)

每个请求都由页面类的新实例处理,因此重置所有实例变量(如您所知)。

您希望保留请求的值应存储在ViewState(在页面中的回发之间存储值)或Session(以保持多个页面之间的值)

注意:将这些值存储在静态变量中。他们确实在回发之间保持价值,但也在所有访问者之间共享。