2011-03-22 73 views
0

我正在尋找在Web應用程序中實現一些模板,並希望利用ASP.NET的模板控件。但是,我不想依賴物理.ascx文件或VirtualPathProvider來加載模板。我可以從數據庫或字符串加載ITemplate嗎?

我希望能夠從數據庫或其他數據存儲(內存中?)加載模板。 是否有LoadTemplate()方法的任何實現,該方法在給定.ascx模板的字符串表示形式的情況下返回ITemplate?

如果不是,我會怎麼寫一個?

僅供參考,Kentico有類似的功能,但他們爲了在TemplateControl類使用LoadTemplate()依靠VirtualPathProvider。用這種方法,他們能夠加載存儲在數據庫中的模板(他們稱之爲轉換)。

+0

我在Sitefinity也看到過這個,如果我沒有記錯的話,我認爲這是最好的選擇。或者你可以爲ascx標記創建你自己的解析器,但這不是微不足道的。 – Robert 2011-03-22 15:27:06

+0

是的,我認爲很多基於.NET的CMS和其他可擴展應用程序都使用這種方法。它看起來像是微不足道的,我發現很難理解爲什麼有一個物理的ASCX文件和一個字符串變量有什麼不同。 – 2011-03-22 20:16:20

回答

1

是的,VirtualPathProvider可能是您希望使用的方法,如果字符串或數據庫是您要使用的源。 (也有代碼生成器,可以發出代碼,但通常這些都是動態構建代碼時使用 - 從外部源作爲你的情況不加載)

你不提爲什麼你不」不過想要使用VirtualPathProvider。是否由於您在特定情況下的某些特殊要求而不想或者不能?最後,如果它「動態地加載和編譯代碼」看起來微不足道,那麼在它可以運行動態代碼 - 程序集生成,編譯和JIT之前,你不知道整個.NET系統必須做什麼,應用程序上下文,類/成員名稱解析,代碼安全性等。也許你剛剛被寵壞了.net已經完成了其他複雜任務。 ;-)

1

我一直在面對類似的問題。然而,VirtualPathProvider僅僅是爲了實現如此小的收益而過於沉重 - 更不用說它似乎有可能在安全方面有點風險實施。我已經發現了兩個可能的變通:

1)使用反射來獲取你想要的東西:

var page = HttpContext.Current.Handler as Page; 
string text = "<table><tr><td>Testing!!!</td></tr></table>"; 
var systemWebAssembly = System.Reflection.Assembly.GetAssembly(typeof(Page)); 
var virtualPathType = systemWebAssembly.GetTypes().Where(t => t.Name == "VirtualPath").FirstOrDefault(); // Type.GetType("System.Web.VirtualPath"); 
var createMethod = virtualPathType.GetMethods(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public).Where(m => m.Name == "Create" && m.GetParameters().Length == 1).FirstOrDefault(); 
object virtualPath = createMethod.Invoke(null, new object[] 
{ 
    page.AppRelativeVirtualPath 
}); 
var template = (ITemplate)typeof(TemplateParser).GetMethod("ParseTemplate", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).Invoke(null, new object[]{text, virtualPath, true}); 

2)使用一個有點哈克變通:

var page = HttpContext.Current.Handler as Page; 
string text = "<table><tr><td>Testing!!!</td></tr></table>"; 
string modifiedText = string.Format("<asp:UpdatePanel runat=\"server\"><ContentTemplate>{0}</ContentTemplate></asp:UpdatePanel>", text); 
var control = page.ParseControl(modifiedText); 
var updatePanel = control.Controls[0] as UpdatePanel; 
var template = updatePanel.ContentTemplate; 

我公開的管理員認爲這兩者都不是很好的解理想情況下,在.Net框架中會有這種方法。類似於:

public class TemplateParser 
{ 
    public static ITemplate ParseTemplate(string content, string virtualPath, bool ignoreParserFilter) 
    { 
     return TemplateParser.ParseTemplate(string content, VirtualPath.Create(virtualPath), ignoreParserFilter); 
    } 
} 

這將緩解整個實施VirtualPathProvider的需要。也許我們會在ASP.NET vNext中看到:-)

+0

請注意,我在ASP.Net論壇中發佈了此請求: – mhildreth 2011-10-31 13:52:19

+0

http://forums.asp.net/t/1735312.aspx/1?Feature+Request+to+alleviate+need+for+的VirtualPathProvider – mhildreth 2011-10-31 13:52:34

相關問題