C# 加载动态创建的ASCX控件(通过代码)

C# 加载动态创建的ASCX控件(通过代码),c#,asp.net,user-controls,webusercontrol,dynamic-compilation,C#,Asp.net,User Controls,Webusercontrol,Dynamic Compilation,我通过代码创建Web用户控件(我的C#代码将标记、代码隐藏和设计器文件写入回调磁盘)。这些控件都创建得很好。我可以将它们添加到我的web项目中,并将它们放在页面上 当我尝试使用LoadControl(path)加载控件时,它会显示: Unable to load type 'MyNameSpace.UseControlClass' 这是因为控件尚未编译 但我的要求是动态加载控件,而无需重新编译解决方案 如何仅在创建控件文件时编译用户控件?因为这似乎是唯一的出路 编辑:-我的猜测是,由于文件尚未

我通过代码创建
Web用户控件
(我的C#代码将标记、代码隐藏和设计器文件写入回调磁盘)。这些控件都创建得很好。我可以将它们添加到我的web项目中,并将它们放在页面上

当我尝试使用
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" });
但它抱怨
找不到元数据文件Telerik.Web.Design.dll
等。我不想硬编码Telerik路径,因为它在托管系统中可能不同(尽管它在当前Web应用的
bin
中)。另外,
MyCurrentDll.dll
是我编译代码文件的文件的dll。我如何解决这个问题

我的想法是编译代码文件,动态创建
dll
,并将其复制到web应用程序的
bin
目录。它可能会解决我最初提出的问题

编辑2:-点击并试用后,我能够动态编译代码文件并生成
dll
。即使在生成dll并将其放入应用程序的
bin
之后,我也无法使用
virtualpath
加载用户控件。我尝试过以下方法:

var asm = Assembly.Load("ddlPath");
var t = asm.GetType(fullTypeName);//NameSpace.Class
var ctrl = LoadControl(t,null);
在此之后加载ctrl。我分配其
Id
属性,并将其添加到
asp.net面板
控件中。但在回发后不可见:(

现在,我必须以某种方式使动态编译的dll类型可用于运行时(可能是appdomain),这样当我使用虚拟路径加载控件时,它会被正确加载,并且我不会得到
HtmlParseException
,或者弄清楚为什么加载控件表单
Type
不会出现


PS:-我已经使用
类型加载了
标签
控件,并且它工作正常。

hmm。您考虑过为此使用吗

包含共享类和业务对象的源代码(用于 例如,…cs和.vb文件),您希望将其编译为 在动态编译的网站项目中,ASP.NET 在首次请求时编译App_code文件夹中的代码 您的应用程序。如果存在此文件夹中的项目,则会重新编译它们 检测到更改


最后我终于解决了这个问题。以下是我采取的策略:

  • 创建包含
    代码隐藏
    标记
    设计器
    代码结构的文本文件
  • 阅读有关要创建哪些字段的信息
  • 为字符串生成器中所需的控件放置标记
  • 将一些其他相关信息放入更多字符串生成器中
  • 写文件
  • 在此之后,我使用
    CodeDome
    编译器创建了
    dll
    。编译过程中遇到的主要问题,如问题的
    编辑部分所述,是找不到引用的程序集,这通过将
    bin
    目录的路径与dll文件名放在一起解决,如:

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

    在EDIT2中概述的下一个问题稍微简单一点。有点愚蠢。在动态生成的用户控件中嵌入的另一个用户控件中有一些问题


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

    中解析类型,这是一个非常有趣的问题。我想不出用于此的用例-但我通常使用的方式是这种方法是让另一个程序集知道如何构建控件,并在运行时发出HTML等。也许在这里可以采用类似的方法,将新控件嵌入另一个程序集中,然后从中编译和加载?我会感兴趣地关注这个问题!@dash用例是我们允许用户将一些IELD(具有预定义的输入类型)并从最终用户处获取输入。我想创建一个用户控件,嵌入这些字段。您的控件和托管页是否在CodeFile而不是CodeBehind中?您是否尝试过将用户控件放在同一解决方案中的其他项目中?您可以将输出dll配置到主项目中的bin中。@user551263如何在托管在服务器?@jbl我不明白你的意思是什么?你是说用户控件标记文件中的
    CodeFile
    codebeard
    属性?这对我没有帮助,因为我正在创建用户控件,并且文件也是在运行时动态创建的。问题是在应用程序域中加载创建的文件以创建控件对象。我知道我已经解决了这个问题,很快就会给出答案。