我通過代碼(我的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