本帖最后由 hoho2010 于 2010-07-23 17:53:26 编辑

解决方案 »

  1.   

    如何解决ASP.NET2.0中用户控件无法编译和动态加载的问题
    目前的项目用了比较多的模版和用户控件(User Controls),并且有许多是动态加载(LoadControl方式)。
    在部署之前,需要把整个站点先予编译好,这样一则可以提高首次访问时的加载速度,另外对安全性也有益处。
    但是在编译的时候,由于动态加载用户控件,会出现命名空间不存在的错误(如 The type or namesapce name "MyDefaultNav" does not exists in the namespace 'ASP'(are you missing an assembly reference?))。
    这个问题是由于项目编译选项默认选择了Allow this precompiles site to be updatable,只要把这个选项去掉重试即可,这背后的深层次的原因目前还不是很清楚,应该是由于ASP.NET新的编译模式引起的,等有时间的时候再好好研究一番。 
    但是,在把编译后的应用部署之后,遇到了另一个问题,发现用户控件无法加载,而其它功能却一切正常。检查之后发现,原来是因为我们的代码中使用了LoadControl("~/UserCtrls/DefaultNav.ascx")这种方式。而ASP.NET2.0编译之后,所有的用户控件文件(.ascx)都会完全编译到dll中,原来的文件已经彻底删除(而.aspx文件则会留一个空壳文件),所以指向原文件链接的这种加载方式就会失效。后来发现,ASP.NET 2.0为了解决这个问题,为LoadControl添加了一个新的函数变体,LoadControl (Type, Object[]) ,采用类型的方式加载用户控件,而不是文件路径方式。 
    这种加载方式的需要在用的aspx里采用<%@ Reference Control="~/UserCtrls/DefaultNav.ascx" %>先添加对用户控件的引用,同时要在.ascx的<@ Control ClassName="MyDefaultNav" ... %>里添加ClassName显式定义用户控件类型。然后在代码里就可以通过一下方式动态加载这个用户控件了。
                    ASP.MyDefaultNav navCtr = (ASP.MyDefaultNav)LoadControl(typeof(ASP.MyDefaultNav), null);
                  navPh.Controls.Add(navCtr); 
    完成这些代码之后,在预编译的站点上就能正常地应用用户控件了。
     
    当然,也有另外一种解决方法,那就是用户控件转换成自定义控件(Custom Controls),编译成单独的dll之后,在aspx里直接应用这个dll,那就不会存在动态加载问题。而且,自定义空间可以在多个web applications之间共享,而用户控件只能在当前的web application中使用。
      

  2.   


    在ASP.NET中动态加载内容(用户控件和模板) 要点: 1. 使用Page.ParseControl 2. 使用base.LoadControl 第一部分:加载模板 下面是一个模板“<table width=100%><tr><td width=100% colspan=2 runat=server id=ContainerTop></td></tr><tr><td width=30% runat=server id=ContainerLeft></td><td width=70% runat=server id=ContainerRight></td></tr></table>”如何把它添加到页面中那。  
    首先,你要有一个页面(.ASPx),在页面中有一个一行一列的表格,并且是服务器端的TD我们就把它命名为TemplateContainer。好了现在到代码编辑窗口,在page_load中加载模板。 第二步,使用Page.ParseControl将上边的HTML代码分析为web窗体页或用户控件的System.web.ui.control如下代码: protected System.Web.UI.HTMLControls.HTMLTableCell TemplateContainer; System.Web.UI.Control objContainer; private void Page_Load(object sender, System.EventArgs e) { objContainer =Page.ParseControl(“上边的HTML代码); this.TempContainer.Controls.Add(objContainer); } 模板已经加载完毕。 第二部分:加载用户控件 首先,你要确定用户控件要加载到页面的那个位置。现在你会发现第一部分的那段HTML代码,其中每一个TD都是一个容器你可以通过Page.FindControl找到你要加载控件的容器。如下代码: System.Web.UI.Control objControl=Page.FindControl("ContainerTop"); 第二,找到容器后,就可以将你的用户控件加载到页面中了。如下代码: objControl.Controls.Add(base.LoadControl(“用户控件虚拟路径”)); 现在运行程序看看,是不是已经加载了用户控件。 
    以上是动态加载模板和用户控件的一些主要部分,要想做一个比较好的页面还需要加入许多必要的东西,如将模板和用户控件的虚拟路径都保存到数据库中、对页面已经加载了的用户控件进行位置的调整。对权限的控制如那些人可以看什么用户控件那些人不可以 看用户控件,等等。 下面中一个例子:http://elt.nec.edu.cn,不过在这里你不能调整用户件位置。(我当然可以了)在这个例子中的导航栏也是动态加载的,不同的页可能使用不同的模板加载不同的用户控件。 
      

  3.   

    ASP.MyDefaultNav navCtr = (ASP.MyDefaultNav)LoadControl(typeof(ASP.MyDefaultNav), null);
      navPh.Controls.Add(navCtr);在编译时说找不到asp的命名空间!
      

  4.   

    LoadControl加载控件
    FindControl查找
    UserControl myusercontrol = (UserControl) LoadControl ("myusercontrol1.ascx") ; 
    Type myusertype = myusercontrol.GetType();
    或Page.ParseControl
      

  5.   

    把<%@ Reference Control="~/ycIndex/NewsList/NewsList.ascx" %>添加到aspx的上面。这样在编译时就会找到命名空间了
      

  6.   


    我想问你,你凭什么写个“ASP.”呢?就因为有人动不动就提到“ASP命名空间”还是因为你看到了MyDefaultNav这个class的源代码在声明时前边一行确实有“namespace ASP”这种东西?
      

  7.   


    如果你还是在使用7、8年前的asp.net1.1,我的可能有点“幸灾乐祸”的选择是:自作自受。我是完全懒得去维护asp.net1.1甚至asp.net1.0的那些所谓“ASP命名空间”问题的。
      

  8.   

    to sp1234你除了指手画脚,能说一点实质性的内容吗?
      

  9.   

    ASP命名空间是建站网站时默认的全局命名空间,只有建WebApplication时才不是。