2012-04-19 108 views
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