2012-01-03 15 views
9

Mam aplikację internetową, która dynamicznie tworzy stronę internetową za pomocą usercontrols.Type.GetType() zwracająca wartość null

ciągu mojego kodu mam następujące:

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

The "typename", który jest zwrócony (przykład) jest:

IPAMIntranet.IPAM_Controls.webtemplatecontrols.eventorgcommittee

Przestrzeń nazw dla formantów użytkownika jest następująca :

namespace IPAMIntranet.IPAM_Controls 

Problemem, który mam, jest to, że T ype.GetType (typeName) zwraca wartość null. Czego tu mi brakuje?

+0

Tak, przepraszam, błąd w pisaniu, miałem na myśli zerową – mattgcon

Odpowiedz

24

Type.GetType(string) przegląda tylko aktualnie wykonywanego zespołu i mscorlib, jeśli nie podasz nazwy zespołu w ciągu.

Opcje:

  • używać nazwy zespołu wykwalifikowanych zamiast
  • połączeń Assembly.GetType(name) na odpowiednim montażu zamiast

Jeśli masz łatwy sposób dotarcie do właściwego montażu (np przez typeof(SomeKnownType).Assembly), wtedy druga opcja jest prawdopodobnie prostsza.

+0

nazwę kwalifikowaną do montażu? gdzie mam to dostać? Są to niestandardowe formanty użytkownika, które utworzyłem w samej aplikacji internetowej, jeśli to pomaga – mattgcon

+2

@mattgcon: Możesz użyć 'Type.AssemblyQualifiedName', ale jeśli wiesz, że jest to dla konkretnego zespołu, możesz użyć' typeof (SomeClassInTheAssembly) .Assembly' aby uzyskać ten zestaw, użyj 'Assembly.GetType (string)'. Nie ma znaczenia, której klasy używasz ze złożenia, aby uzyskać odniesienie do niego. –

+0

Po otrzymaniu zespołu, co mam zrobić? Czy mogę podać Typ child = Assembly.GetType (typeName), aby uzyskać kontrolę użytkownika? – mattgcon

4

Typ.GetType wygląda jak zestaw wywołujący i kilka zestawów systemowych. Aby uzyskać cokolwiek innego, musisz albo użyć assemblyInstance.GetType(typeName), albo musisz użyć "kwalifikowanej nazwy zestawu" typu, która zawiera szczegóły zespołu, w którym można znaleźć typ. W przeciwnym razie nie zostanie znaleziony i zwróci wartość null. można dostać od:

string aqn = someType.AssemblyQualifiedName; 
+0

jak uzyskać kwalifikowaną nazwę zestawu dla formantów użytkownika – mattgcon

+0

@mattgcon Zawarłem to w odpowiedzi –

+0

, jeśli someType jest moim typeName , Muszę powiedzieć, że funkcja typeName będzie dynamiczna i nie mam pojęcia, co to jest w czasie projektowania. – mattgcon

0

miałem bardzo podobny problem do oryginalnego plakatu, chyba że muszę instancję kodu źródłowego klasy mojego niestandardowego łatwość sterowania w statycznej klasie użytkowej, a nie ASPX stronę, więc LoadControl nie był dla mnie dostępny. Oto, co skończyło się robi:

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

To nie całkiem i nie bardzo wydajny i jest podatne na złamania, jeśli App_Web_ * konwencji nazewnictwa zmieni (choć można to po prostu przejrzeć wszystkie z nich): ale to robi praca ...

Powiązane problemy