Question

Je cherche à implémenter certains modèles dans une application Web et je voulais utiliser les contrôles temporaires d'ASP.NET. Cependant, je ne veux pas compter sur des fichiers .ascx physiques ou sur VirtualPathProvider afin de charger les modèles.

Je veux pouvoir charger les modèles d'une base de données ou d'une autre banque de données (en mémoire?). Existe-t-il une implémentation d'une méthode LoadTemplate () qui renvoie un plateau d'élément étant donné une représentation de chaîne d'un modèle .ascx?

Sinon, comment pourrais-je en écrire un?

FYI, Kentico a une caractéristique similaire, mais ils comptent sur le VirtualPathProvider Afin d'utiliser le LoadTemplate() sur le TemplateControl classer. Avec cette méthode, ils sont capables de charger des modèles (ils les appellent des transformations) stockés dans la base de données.

Était-ce utile?

La solution

Oui, VirtualPathProvider est probablement la méthode que vous souhaitez utiliser, si une chaîne ou une base de données est la source que vous souhaitez utiliser. (Il existe également des générateurs de code qui peuvent émettre du code, mais généralement ceux-ci sont utilisés lors de la construction du code dynamiquement - pas de chargement à partir d'une source externe comme dans votre cas.)

Tu ne mentionne pas Pourquoi Vous ne voulez cependant pas utiliser le VirtualPathProvider. Est-il dû à ne pas vouloir ou à ne peut pas en raison de certaines exigences particulières que vous avez dans une situation particulière?

Enfin, s'il "semble trivial" pour charger et compiler le code dynamiquement, alors vous ne savez pas ce que tout l'ensemble du système .NET a à faire avant de pouvoir exécuter le code dynamique - génération, compilation et JIT, contextes d'application, classe / Résolution du nom du membre, sécurité du code, etc. Peut-être que vous venez d'être gâté avec la facilité avec laquelle .NET a facilité la réalisation d'autres tâches compliquées. ;-)

Autres conseils

J'ai été confronté à un problème similaire. Cependant, le VirtualPathProvider est tout simplement trop de plomberie à mettre en œuvre pour un si petit gain - sans oublier qu'il semble qu'il a le potentiel d'être un peu risqué sur le point de mettre en œuvre. J'ai trouvé deux travaux de travail possibles:

1) Utilisez la réflexion pour obtenir ce que vous voulez:

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) Utilisez un travail de travail quelque peu piraté:

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;

J'admire ouvertement que ni l'un ni l'autre n'est une excellente solution. Idéalement, il y aurait une méthode dans le framework .NET pour ce genre de chose. Quelque chose comme:

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

Cela atténuerait tout le besoin de mettre en œuvre le VirtualPathProvider. Peut-être que nous verrons cela dans asp.net vnext :-)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top