我通过代码(我的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
控制,它工作正常
这是一个非常有趣的问题。我想不出一个用例 - 但我通常的做法是让另一个程序集知道如何在运行时构建控件并发出HTML等。也许类似的方法可以通过将新控件嵌入到另一个程序集中,然后您可以从中进行编译和加载?我会很感兴趣地看这个问题! – dash 2012-04-19 08:03:25
@dash Use case是我们允许用户将一些字段(使用预定义的输入类型)分组,并从最终用户那里获得输入。我想创建一个用户控件,嵌入这些字段。 – TheVillageIdiot 2012-04-19 08:38:17
您的控件和托管页面在CodeFile中而不是在CodeBehind中吗? – jbl 2012-04-19 08:38:21