J'ai une application Web qui crée de manière dynamique une page Web à l'aide d'UserControls.
dans mon code, j'ai ce qui suit: p> Le "typename" qui est en train d'être retourné (exemple) est la suivante: p> L'espace de noms des contrôles de l'utilisateur est comme suit: p> ipamintranet.ipam_controls.webemplplatecontrol.Eventorgcommittee code> p>
namespace IPAMIntranet.IPAM_Controls
3 Réponses :
Options: P>
Si vous avez un moyen facile d'obtenir la maintenance de l'assemblage pertinent (par exemple via type.getType (chaîne) code>
ne regarde que dans le Actuellement exécutant l'assemblage et mscorlib code> lorsque vous ne spécifiez pas le nom de montage dans la chaîne. p>
assembly.getType (nom) code>
sur le assemblée à la place li>
ul>
typeof (certains renseignements). Assembly code>), la deuxième option est probablement plus simple. P>
Nom qualifié de montage? Où dois-je obtenir ça? Ce sont des contrôles utilisateur personnalisés que j'ai créés dans l'application Web elle-même si cela aide
@mattgcon: Vous pouvez utiliser type.assemblyqualifeName code>, mais si vous savez que c'est pour un assemblage spécifique, vous pouvez utiliser
typeof (Soméclassintheasbly). Assembly code> pour obtenir cet ensemble, puis utiliser
Assembly.getType (String) Code>. Peu importe la classe que vous utilisez de l'Assemblée pour y faire une référence.
Après avoir obtenu l'assemblage alors que dois-je faire? Est-ce que j'adore le type enfant = Assembly.getType (typename) pour obtenir le contrôle de l'utilisateur?
@MattgCon: Oui, exactement ... sauf en utilisant la référence de montage au lieu de Assemblage code>.
ok donc j'ai ajouté ce qui suit: 'Assembly Aqn = typeof (webonlinecustombase). Assembly' Alors 'Type Enfant = aqn.gettype (typename)' Mais il retourne toujours null
@mattgcon: alors il ressemble à ce que votre nom de type est incorrect, ou ce type n'est pas dans le même assemblage que webonlinecustombase code>. (Est-ce vraiment le nom d'un type? Vous voudrez peut-être regarder les conventions de nommage .net.)
Laissez-nous Continuer cette discussion en chat
@MattgCon: Désolé, le chat ne fonctionne pas vraiment pour mon style de vie. Collaborons aux commentaires.
Ok pas un problème. Le type est renvoyé à partir d'une base de données SQL avec un type tel que: 'ipamintranet.ipam_controls.webtemplplatecontrols.eventorgcommcontrol.eventorgcommcontrol.eventorgcomm. L'Usercontrol que j'ai créé a un nom de fichier EventorgCommittee.ascx. EventorgCommittee.ascx et webonlinecustombase.ascx sont situés dans le même dossier
@MattgCon: Je ne connais pas les détails de la compilation à la volée dans ASP.NET - Je vous suggère d'essayer d'ouvrir l'une des assemblées générées dans le réflecteur et de voir ce qui y est. Alternativement, essayez de changer votre conception afin que vous n'ayez pas besoin de cette approche ...
Ce que je ne comprends pas, c'est pourquoi dois-je appeler un assemblage différent si les fichiers de contrôle de l'utilisateur ne sont pas compilés à partir d'une DLL et se trouvaient plutôt que des fichiers de mon application Web.
@MattgCon: Eh bien, les types sont en cours de création sur la mouche ... J'espérais que ce serait compiler tous i> des contrôles de l'utilisateur dans un assemblage, ce qui le ferait fonctionner ... mais Si cela ne les compile que sur une base «juste à temps», vous vous retrouverez avec un assemblage par contrôle, ce qui le rend tout plus difficile.
Vous êtes correct dans le fait qu'il s'agit d'un assemblage par contrôle. Voici une question, comment allais-je prendre cette chaîne pour le type et faire un type de (classe) dessus?
@MattgCon: Vous ne pouvez pas, car la référence de type n'est essentiellement connue à la compilée - car elle est compilée au moment de l'exécution.
Hmmm bien qui rend les choses plus difficiles alors. Et cela doit être fait de cette façon.
@mattgcon: Ce n'est pas clair exactement ce que vous entendez par là. Avez-vous avoir i> utiliser des contrôles utilisateur non précompilés? (Si vous les précalisez, ils pourraient tous être dans la même assemblée.) La logique a-t-elle i> dans ces contrôles utilisateur? Vous pouvez avoir une classe qui a essentiellement utilisé typeof code> pour chaque contrôle de l'utilisateur que vous avez soigné, créant un mappage de la chaîne à taper - mais cela obligerait la compilation rapide de toute façon.
Oh, ce que je voulais dire, c'est que le chargement des commandes doit être au moment de l'exécution. Le webonlinecustombase est la base UserControl de toutes les commandes chargées dynamiquement si cela aide
J'aurais peut-être juste résolu mon problème et je reviendrai avec mes résultats
Ok, cela a été résolu en mettant simplement en train de supprimer tout sauf pour le nom de contrôle de Typepath et de la placer dans la déclaration LoadControl.
@MattgCon: Ah, excellent - content que vous avez triché à la fin!
@skeet, en utilisant l'assemblement ... donne une erreur que "une référence d'objet est requise pour le système de champ, de méthode ou de propriété non statique.Reflection.Assembly.getType (chaîne) '
@Aks: D'où la partie "sur la pièce appropriée". Vous devez avoir une référence à l'assemblage pertinent code> premier ...
type.getType ressemble à l'assemblage em> appelant em> et quelques assemblages système. Pour toute autre chose, vous devez soit utiliser montageInstance.gettype (typename) code>, ou vous devez utiliser le "nom de montage qualifié" du type, qui inclut les détails de l'assemblage dans lesquels le type peut être trouvé. Sinon, il ne sera pas trouvé et retournera null. Vous pouvez obtenir cela de:
Comment puis-je obtenir le nom qualifié de montage pour les contrôles utilisateur
@mattgcon je comprends que dans la réponse
Si le MATYPE est MON TYPENAME, je dois dire que le typename va être dynamique et je n'ai aucune idée de ce que c'est pendant le temps de conception.
@matt quelque part, d'une certaine manière, vous avez des cordes. Ce que je dis est: stockez-les comme la version qualifiée de l'assemblage. Ou: s'ils viennent tous de la même dll, utilisez Assembly.getType
Ce n'est pas ce n'est pas des usercontrols précompilats que j'ai ajoutés avec une DLL. Ce sont des fichiers USERCONTROL réels dans l'application Web. Ils sont situés dans un sous-dossier dans l'application Web.
@Web en créer un, et voyez ce que le nom de l'assemblage-qualifié est. IIRC ils suivent un motif.
J'ai eu un problème très similaire à l'affiche originale, sauf que je devais instancier la classe de code de mon contrôle de mon utilisateur personnalisé dans une classe utilitaire statique plutôt que d'une page ASPX, donc chargable de caractères n'était pas disponible pour moi. . Voici ce que j'ai fini par faire:
public static class Utils { public static string MyFunc(string controlClassName) { string result = ""; // get a list of all assemblies in this application domain Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); // the trouble is that we don't know which assembly the class is defined in, // because we are using the "Web Site" model in Visual Studio that compiles // them on the fly into assemblies with random names // -> however, we do know that the assembly will be named App_Web_* // (http://msdn.microsoft.com/en-us/magazine/cc163496.aspx) foreach (Assembly assembly in assemblies) { if (assembly.FullName.StartsWith("App_Web_")) { // I have specified the ClassName attribute of the <%@ Control %> // directive in the relevant ASCX files, so this should work Type t = assembly.GetType("ASP." + controlClassName); if (t != null) { // use reflection to create the instance (as a general object) object o = Activator.CreateInstance(t); // cast to the common base type that has the property we need CommonBaseType ctrl = o as CommonBaseType; if (ctrl != null) { foreach (string key in ctrl.PropertyWeNeed) { // finally, do the actual work result = "something good"; } } } } } return result; } }
oui désolé mon erreur de frappe, je voulais dire null