我一直在面對類似的問題。然而,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中看到:-)
我在Sitefinity也看到過這個,如果我沒有記錯的話,我認爲這是最好的選擇。或者你可以爲ascx標記創建你自己的解析器,但這不是微不足道的。 – Robert 2011-03-22 15:27:06
是的,我認爲很多基於.NET的CMS和其他可擴展應用程序都使用這種方法。它看起來像是微不足道的,我發現很難理解爲什麼有一個物理的ASCX文件和一個字符串變量有什麼不同。 – 2011-03-22 20:16:20