我可以从数据库或字符串加载 ITemplate 吗?

发布于 2024-10-25 04:08:01 字数 427 浏览 4 评论 0原文

我希望在 Web 应用程序中实现一些模板,并希望利用 ASP.NET 的模板化控件。但是,我不想依赖物理 .ascx 文件或 VirtualPathProvider 来加载模板。

我希望能够从数据库或其他数据存储(在内存中?)加载模板。 是否有任何 LoadTemplate() 方法的实现,该方法在给定 .ascx 模板的字符串表示形式的情况下返回 ITemplate?

如果没有,我将如何编写一个?

仅供参考、Kentico 具有类似的功能,但它们依赖于 VirtualPathProvider 才能在 TemplateControl 类上使用 LoadTemplate()。通过该方法,他们能够加载存储在数据库中的模板(他们称之为转换)。

I'm looking to implement some templates in a web application and wanted to utilize ASP.NET's templated controls. However, I don't want to rely on physical .ascx files, or the VirtualPathProvider in order to Load the templates.

I want to be able to load the templates from a database or other datastore (in memory?). Is there any implementation of a LoadTemplate() method that returns an ITemplate given a string representation of an .ascx template?

If not, how would I go about writing one?

FYI, Kentico has a similar feature, but they rely on the VirtualPathProvider in order to use the LoadTemplate() on the TemplateControl class. With that method, they are able to load templates (they call them transformations) stored in the database.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

是你 2024-11-01 04:08:01

是的,如果您要使用字符串或数据库作为源,VirtualPathProvider 可能就是您想要使用的方法。 (也有可以发出代码的代码生成器,但通常在动态构建代码时使用它们 - 而不是像您的情况那样从外部源加载。)

您没有提到您为什么不这样做但不想使用 VirtualPathProvider。是因为在特定情况下有一些特殊要求而不愿意或不能吗?

最后,如果动态加载和编译代码“看起来微不足道”,那么您不知道整个 .Net 系统在运行动态代码之前必须做什么——程序集生成、编译和 JIT、应用程序上下文、类/成员名称解析、代码安全性等。也许您只是被 .Net 使执行其他复杂任务变得如此容易而宠坏了。 ;-)

Yes, VirtualPathProvider is probably the method you will want to use, if a string or database is the source you want to use. (There are also code generators that can emit code, but usually those are used when building the code dynamically--not loading from an external source as in your case.)

You don't mention why you don't want to use the VirtualPathProvider though. Is it due to not wanting to, or can't because of some special requirements you have in a particular situation?

Finally, if it "seems trivial" to load and compile code dynamically, then you don't know what all the whole .Net system has to do before it can run dynamic code--assembly generation, compilation and JIT, application contexts, class/member name resolution, code security, etc. Maybe you've just been spoiled with how easy .Net has made doing other complicated tasks. ;-)

乱世争霸 2024-11-01 04:08:01

我也遇到过类似的问题。然而,为了获得如此小的收益,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)使用有点hacky的解决方法:

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 Framework 中应该有一个方法来处理此类事情。类似于:

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 中看到这一点:-)

I've been facing a similar problem. However, the VirtualPathProvider is just too much plumbing to implement for such a small gain - not to mention that it seems like it has the potential to be a bit risky security-wise to implement. I've found two possible work-arounds:

1) Use reflection to get at what you want:

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) Use a somewhat hacky work-around:

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;

I openly admin that neither is a great solution. Ideally, there would be a method in the .Net Framework for this sort of thing. Something like:

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

That would alleviate the whole need to implement the VirtualPathProvider. Maybe we'll see that in ASP.NET vNext :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文