我通过代码创建Web User Controls
(我的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" });
但它抱怨cannot find metadata file Telerik.Web.Design.dll
等。我不想对telerik路径进行硬编码,因为它在托管系统中可能有所不同(尽管它位于当前网络应用程序的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: - 我使用Label
加载了Type
控件,但它运行正常。
答案 0 :(得分:2)
最后我能够解决问题。以下是我采用的策略:
CodeBehind
,Markup
和Designer
代码在此之后,我使用dll
编译器创建了CodeDome
。编译过程中遇到的主要问题,如 Edit
部分问题所述,未找到引用的程序集,通过将bin
目录的路径与dll文件放在一起来解决名字如:
Server.MapPath("~/bin")+"\\Telerik.Web.dll"
等
EDIT2
中列出的下一个问题有点简单。有点愚蠢。嵌入动态生成的用户控件中的另一个用户控件存在一些问题。
即使在此之后,我也无法将控件加载到编译代码的页面中。当我在另一页中加载控件时,这已得到解决。运行时能够从动态编译的dll
解析类型。
答案 1 :(得分:1)
嗯..您是否考虑过将App_Code folder用于此目的?
包含共享类和业务对象的源代码(for 例如,.. ccs和.vb文件)你想要编译为你的一部分 应用。在动态编译的Web站点项目中,ASP.NET 在初始请求中编译App_Code文件夹中的代码 你的申请。然后重新编译此文件夹中的项目 检测到更改。