2012-01-03 22 views
9

Tengo una aplicación web que crea dinámicamente una página web utilizando controles de usuario.Type.GetType() return null

Dentro de mi código tengo el siguiente:

private void Render_Modules() 
    { 
     foreach (OnlineSystemPageCustom.OnlineSystemPageHdr.OnlineSystemPageModule item in custompage.Header.Modules) 
     { 
      if (item.ModuleCustomOrder != 99 && !item.ModuleOptional) 
      { 
       string typeName = item.ModuleInternetFile; 
       Type child = Type.GetType(typeName); 
       webonlinecustombase ctl = (webonlinecustombase)Page.LoadControl("../IPAM_Controls/webtemplatecontrols/" + child.Name.ToString() + ".ascx"); 
       ctl.Event = Event; 
       ctl.custompage = custompage; 
       ctl.custommodule = item; 
       this.eventprogrammodules.Controls.Add(ctl); 
      } 
     } 
    } 

El "typeName" que está siendo devuelto (ejemplo) es:

IPAMIntranet.IPAM_Controls.webtemplatecontrols.eventorgcommittee

El espacio de nombres para los controles de usuario es el siguiente :

namespace IPAMIntranet.IPAM_Controls 

El problema que estoy teniendo es que T ype.GetType (typeName) devuelve nulo. ¿Que me estoy perdiendo aqui?

+0

sí, lo siento, mi error de tipeo, quise decir nulo – mattgcon

Respuesta

24

Type.GetType(string) solo se ve en el ensamblado que se está ejecutando actualmente y mscorlib cuando no especifica el nombre del ensamblado dentro de la cadena.

Opciones:

  • utilizar el nombre de ensamblado-cualificada en lugar
  • llamada Assembly.GetType(name) en el conjunto adecuado en lugar

Si usted tiene una manera fácil de conseguir controlar la Asamblea relevante (por ejemplo, a través de typeof(SomeKnownType).Assembly) entonces la segunda opción es probablemente más simple.

+0

nombre calificado para montaje? ¿De dónde saco eso? Estos son controles de usuario personalizados que he creado dentro de la aplicación web si eso ayuda a – mattgcon

+2

@mattgcon: Puede usar 'Type.AssemblyQualifiedName', pero si sabe que es para un ensamblaje específico, puede usar' typeof (SomeClassInTheAssembly) .Assembly' para obtener ese ensamblaje, entonces use 'Assembly.GetType (string)'. No importa qué clase use del conjunto para obtener una referencia. –

+0

Después de obtener el ensamblaje, ¿qué debo hacer? ¿Declaro Type child = Assembly.GetType (typeName) para obtener el control del usuario? – mattgcon

4

Type.GetType se ve como llamando al ensamblaje, y algunos ensambles del sistema. Para cualquier otra cosa, debe usar assemblyInstance.GetType(typeName), o debe usar el "nombre calificado de ensamblado" del tipo, que incluye los detalles de ensamblaje en los que se puede encontrar el tipo. De lo contrario, no se encontrará y devolverá nulo. Usted puede conseguir que a partir de:

string aqn = someType.AssemblyQualifiedName; 
+0

cómo obtengo el nombre calificado de ensamblaje para los controles de usuario – mattgcon

+0

@mattgcon Incluí eso en el contestador –

+0

si el tipo de tipo es mi typeName , Tengo que decir que typeName va a ser dinámico y no tengo ni idea de lo que es durante el tiempo de diseño. – mattgcon

0

que tenía un problema muy similar al creador original, excepto que necesitaba para crear instancias de la clase de código subyacente de mi costumbre de usuario y controles en una clase de utilidad estática en lugar de un ASPX página, por lo que LoadControl no estaba disponible para mí. Esto es lo que terminé haciendo:

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; 
    } 
} 

no es bonito y no muy eficiente, y es susceptible de romperse si el App_Web_ * convención de nomenclatura cambia (aunque se podría entonces sólo mirar a través de todos ellos): pero lo hace trabajar ...

Cuestiones relacionadas