5

我通过代码(我的C#代码写出标记,代码隐藏和设计器文件到回调中的磁盘)创建Web User Controls。控件创建得很好。我可以将它们添加到我的Web项目中并将它们放在页面上。加载ASCX控件动态创建(通过代码)

当我尝试加载使用LoadControl(path)它说的控制:这是因为控制尚未编译

Unable to load type 'MyNameSpace.UseControlClass' 

但我的要求是动态加载控件,而无需重新编译解决方案。

只有当我创建控制文件时,如何编译用户控件?因为这似乎是唯一的出路。

编辑: - 我的猜测是,由于该文件尚未编译,因此不允许在运行时加载。我试图使用CodeDom编译器编译代码文件。像:

var filePath = Server.MapPath(path); 
var provider = CSharpCodeProvider.CreateProvider("C#"); 
var opts = new CompilerParameters(new[] { "mscorlib.dll", "System.Web.dll", 
           "Telerik.Web.Design.dll", "Telerik.Web.UI.dll", 
           "Telerik.Web.UI.Skins.dll", "MyCurrentDll.dll"}); 
opts.GenerateExecutable = false; 
opts.GenerateInMemory = true; 
var cr = provider.CompileAssemblyFromFile(opts, new string[] { filePath+".cs" }); 

但抱怨cannot find metadata file Telerik.Web.Design.dll等等。我不想硬编码Telerik的路径,因为它可能会在托管系统不同(尽管它是当前Web应用程序的bin)。另外MyCurrentDll.dll是我从中编译代码文件的文件的dll。我该如何解决这个问题?

我的想法是编译代码文件动态创建一个dll并将其复制到Web应用程序的bin目录中。它可能解决我原先所说的问题。

编辑2: - 命中和试用后,我能够动态编译代码文件并生成dll。即使在生成DLL并将其放入我的应用程序的bin后,我无法使用virtual path加载用户控件。我试过以下方法:

var asm = Assembly.Load("ddlPath"); 
var t = asm.GetType(fullTypeName);//NameSpace.Class 
var ctrl = LoadControl(t,null); 

ctrl在此之后加载。我分配其Id属性并将其添加到asp.net Panel控件。但它回传后不可见:(

现在我要么以某种方式使动态编译的DLL的类型可用于运行时(appdomain,也许),以便当我加载控制使用虚拟路径它正确加载,我没有得到HtmlParseException或弄清楚为什么加载控制形式Type没有显示出来

PS: - 我已加载使用Type一个Label控制,它工作正常

+0

这是一个非常有趣的问题。我想不出一个用例 - 但我通常的做法是让另一个程序集知道如何在运行时构建控件并发出HTML等。也许类似的方法可以通过将新控件嵌入到另一个程序集中,然后您可以从中进行编译和加载?我会很感兴趣地看这个问题! – dash 2012-04-19 08:03:25

+0

@dash Use case是我们允许用户将一些字段(使用预定义的输入类型)分组,并从最终用户那里获得输入。我想创建一个用户控件,嵌入这些字段。 – TheVillageIdiot 2012-04-19 08:38:17

+0

您的控件和托管页面在CodeFile中而不是在CodeBehind中吗? – jbl 2012-04-19 08:38:21

回答

2

最后我能解决问题。以下是我采取的策略:

  1. 创建一个包含CodeBehindMarkupDesigner代码
  2. 结构的文本文件阅读信息,以什么领域创造。
  3. 将字符串构建器中所需控件的标记放入。
  4. 把一些其他的相关信息为更多的字符串建设者
  5. 写入文件

在此之后我用CodeDome编译器创建的dll。在编译过程中面临的主要问题,有问题的Edit部分所描述的,是没有找到引用的组件,它是通过将bin目录的路径的路径以dll文件名一起像解决:

Server.MapPath("~/bin")+"\\Telerik.Web.dll" 

下一个问题概述在EDIT2有点简单。相当无助。嵌入在动态生成的用户控件中的另一个用户控件存在一些问题。

即使在这之后,我无法将控件加载到编译代码的页面中。当我将控件加载到另一个页面时,这已经解决了。运行时能够从动态编译的dll解析类型。

+0

您可以标记接受的答案,以便将其从未答复的队列中删除吗? – 2012-09-05 01:20:13

1

嗯..你用考虑。 App_Code folder为此目的?

包含要作为 应用程序的一部分编译的共享类和业务对象(适用于 示例,..cs和.vb文件)的源代码。在动态编译的网站项目中,ASP.NET 将初始请求中的App_Code文件夹中的代码编译为 您的应用程序。当检测到任何 更改时,此文件夹中的项目将重新编译。

+0

这不会帮助我,因为我正在创建一个用户控件,并且这些文件也是在运行时动态创建的。问题是加载应用程序域中创建的文件来创建控制对象。我已经解决了它,很快就会发布答案。 – TheVillageIdiot 2012-04-20 04:50:31