您的位置:首页 > 编程语言 > ASP

未将对象引用设置到对象实例(转)

2016-07-05 17:29 459 查看
未将对象引用设置到对象实例(转) 

        最近在做一个涉及操作服务器物理文件夹的交互网页,牵扯到两个出问题控件treeview和asp:imagebutton

  我的目的是让treeview生成文件夹目录树,用户点击结点后,触发事件获取结点的物理路径,并通过imgbtn控件回发给服务器,对该路径执行一定的操作;

  问题是:每次点击目录树结点后能够成功捕获物理路径:

  string selectedpath;//全局变量

  protected void folderTree_SelectedNodeChanged(object sender, EventArgs e)

    {

        selectedpath = folderTree.SelectedNode.ValuePath.Split('/')[folderTree.SelectedNode.ValuePath.Split('/').Count()-1].ToString());

    }

  但之后一旦点击了imgbtn:

    public void imgbtn_Click(object sender, ImageClickEventArgs e)

    {

   Response.Write(selectedpath);

    }

  页面上不会有任何显示,单步调试发现触发按钮事件后selectedpath值为null;

       一同工作的朋友也发现类似的问题,诸如listbox点击后无返回值等;

  于是我将获取路径的代码在按钮事件中重复了一遍:  

    public void imgbtn_Click(object sender, ImageClickEventArgs e)

    {

   selectedpath = folderTree.SelectedNode.ValuePath.Split('/')[folderTree.SelectedNode.ValuePath.Split('/').Count()-1].ToString());

   Response.Write(selectedpath);

    }

  再次调试,红色代码部分报错“未将对象引用到实例”,可是控件本身是存在的,根本不需要实例化

  网上搜索了下,针对listbox,gridview等等控件也遇到了同样的未实例化问题;

  一开始怀疑,是不是treeview这个控件本身不支持在控件定义的事件之外调用控件方法呢?看了treeview的蓝皮定义得知,这个控件本身就可以异步回调,不会导致对整个页面的刷新,于是问题纠结到这个btn上;

  究其原因,其实是imagebutton在点击时会将整个页面同步回调,不论该btn是否有实质性的操作,即将整个页面上所有控件全部初始化,这当然也包括全局变量和label控件,所以想要借用其他控件来暂存也是不可能的。而在刷新页面后,treeview尚没有结点获得selected,因而使用SelectedNode会使引擎无法识别,出现“未将对象引用到实例”的错误。

  解决的方法是利用.NET 4的状态引擎,最简单的是使用viewstate,它可以将预存储的值(必须是字符串)在页面刷新时一并回送到服务器上,当服务器发回响应时这个viewstate也会随响应一并发回。目前viewstate对我最大的用处之一是用来存储字符串值,另一个用处是记录用户对客户端控件的操作,保证响应结果送回时控件不会初始化,比如treeview的折叠打开状况;有关状态引擎及状态管理建议大家看看wrox的Professional ASP.NET 4,在状态管理一章有很多类似viewstate的机制可供在不同情况下选择;

  ASP.NET还是应该系统的看看书,也许实践出真知,但是如果准备不足,细小地方上的磕绊很耽误时间,这是身为.NET初学者给大家的一点经验之谈^_^

另:附上为解决这个问题所走的弯路:

1.将asp:imagebutton的OnClientClick设置为return false;

  一旦这样设置,这个button就只能执行客户页面的脚本,除非编程设置属性开启,否则无法再向服务器回送,也无法手动控制回送时机;

2.在事件中加入逻辑if(!Page.IsPostBack);

  只能用于判断页面是否刷新过,对于需要多次点击的事件不是太适合

3.在微软MSDN的技术资源库中列举了如何实现客户端回调的案例,传送门:

  http://msdn.microsoft.com/zh-cn/library/ms178210(v=VS.80).aspx

  主要是借助了System.Web.UI.ICallbackEventHandler类,还需要有一定的js功底,初学者如果不熟悉js,还是会看的一知半解的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息