2011-03-22 69 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

相关问题