0

Webアプリケーションにいくつかのテンプレートを実装したいと考えており、ASP.NETのテンプレート化されたコントロールを利用したいと考えています。ただし、テンプレートをロードするために、物理的な.ascxファイルやVirtualPathProviderに依存したくありません。

データベースまたは他のデータストア(メモリ内?)からテンプレートをロードできるようにしたい。 .ascxテンプレートの文字列表現を指定してITemplateを返すLoadTemplate()メソッドの実装はありますか?

そうでない場合は、どのように作成しますか?

参考までに、Kenticoにも同様の機能がありますが、クラスでVirtualPathProviderを使用するためにに依存しています。その方法で、彼らはデータベースに保存されたテンプレート(彼らはそれらを変換と呼びます)をロードすることができます。LoadTemplate()TemplateControl

4

2 に答える 2

1

私も同様の問題に直面しています。ただし、VirtualPathProviderは、このような小さな利益のために実装するにはあまりにも多くの配管が必要です。言うまでもなく、実装するのはセキュリティ面で少しリスクが高い可能性があるようです。私は2つの可能な回避策を見つけました:

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;

私は、どちらも優れたソリューションではないことを公然と管理しています。理想的には、この種のもののためのメソッドが.NetFrameworkにあるでしょう。何かのようなもの:

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

これにより、VirtualPathProviderを実装する必要性全体が軽減されます。たぶん、ASP.NETvNextでそれを見るでしょう:-)

于 2011-10-07T13:25:30.780 に答える
1

はい、VirtualPathProvider文字列またはデータベースが使用したいソースである場合、おそらく使用したい方法です。(コードを出力できるコードジェネレーターもありますが、通常、コードを動的にビルドするときに使用されます。たとえば、外部ソースからロードするのではありません。)

ただし、VirtualPathProviderを使用したくない理由については言及していません。それはあなたが特定の状況で持っているいくつかの特別な要件のためにしたくない、またはできないためですか?

最後に、コードを動的にロードしてコンパイルするのが「簡単に思える」場合は、動的コードを実行する前に.Netシステム全体が何をしなければならないかわかりません(アセンブリ生成、コンパイル、JIT、アプリケーションコンテキスト、クラス)。 / memberの名前解決、コードのセキュリティなど。.Netが他の複雑なタスクを簡単に実行できるようになったことで、あなたは甘やかされてしまったかもしれません。;-)

于 2011-08-30T18:18:08.043 に答える