Tuesday, March 13, 2012

Trouble with Type.GetType

Jacob,

what would you like me to use for MyAssembly (is this the assembly I create
with my project?) and SampleAssembly?

What I want to do is dynamically add an (unknown) amount of controls to a
web page at runtime. For not to loose them when I do a roundtrip back to the
server I need to store them somehow (when going back to the server) and
afterwards recreate them. To reconstruct what I tried to do create an empty
page and place a System.Web.UI.WebControls.PlaceHolder labelled PlaceHolder1
and a System.Web.UI.WebControls.Button labelled Button1 on it.

Then put the following code in the code behind file:

Public Class WebForm1

Inherits System.Web.UI.Page

#Region " Vom Web Form Designer generierter Code "

'Dieser Aufruf ist fr den Web Form-Designer erforderlich.

<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()

End Sub

Protected WithEvents PlaceHolder1 As
System.Web.UI.WebControls.PlaceHolder

Protected WithEvents Button1 As System.Web.UI.WebControls.Button

'HINWEIS: Die folgende Platzhalterdeklaration ist fr den Web
Form-Designer erforderlich.

'Nicht lschen oder verschieben.

Private designerPlaceholderDeclaration As System.Object

Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Init

'CODEGEN: Dieser Methodenaufruf ist fr den Web Form-Designer
erforderlich

'Verwenden Sie nicht den Code-Editor zur Bearbeitung.

InitializeComponent()

End Sub

#End Region

Private counter As System.Int32 = 0

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

' Hier Benutzercode zur Seiteninitialisierung einfgen

counter = Session.Item("Counter")

End Sub

Private Sub AddControls(ByVal strLabel As String)

Dim myNewLabel As New System.Web.UI.WebControls.Label

Dim myNewText As New System.Web.UI.WebControls.TextBox

' counter to give objects different names

counter += 1

Session.Item("counter") = counter

myNewLabel.ID = String.Format("myNewLabel{0}", counter)

myNewLabel.Text = strLabel

myNewLabel.EnableViewState = True

' save controls for ViewState

Dim dynControls As System.Collections.ArrayList

dynControls = Viewstate.Item("dynControls")

' create new ArrayList if it does not exist

If dynControls Is Nothing Then

dynControls = New System.Collections.ArrayList

End If

'store information about control in Triplet

Dim labelTrip As New System.Web.UI.Triplet

labelTrip.First = myNewLabel.ID

labelTrip.Second = myNewLabel.GetType.ToString

labelTrip.Third = PlaceHolder1.ID

dynControls.Add(labelTrip)

' put control on Placeholder

PlaceHolder1.Controls.Add(myNewLabel)

' and save information about control in ViewState

ViewState("dynControls") = dynControls

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

AddControls("Created From Button")

End Sub

Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)

Dim dynControls As System.Collections.ArrayList

dynControls = ViewState.Item("dynControls")

If Not dynControls Is Nothing Then

' run through all saved controls

For Each obj As System.Object In dynControls

Dim ctlTrip As System.Web.UI.Triplet

ctlTrip = CType(obj, System.Web.UI.Triplet)

Dim parent As System.Web.UI.WebControls.PlaceHolder

parent = Page.FindControl(ctlTrip.Third)

Dim ctl As System.Web.UI.Control

Try

' THE ERROR OCCURS HERE

' TAKE A LOOT AT THE END OF THE CODE TO SEE THE EXACT
ERROR MESSAGE

ctl =
Activator.CreateInstance(Type.GetType(ctlTrip.Seco nd, True))

Catch ex As Exception

Response.Write(ex.Message)

End Try

ctl.ID = ctlTrip.First

parent.Controls.Add(ctl)

Next

End If

End Sub

End Class

ERROR MESSAGE (from the direct window):

? Type.GetType(ctlTrip.Second, True)

Laufzeitausnahme: System.TypeLoadException - Der Typ
System.Web.UI.WebControls.Label in der Assembly DynamicControlsAdd,
Version=1.0.1381.35345, Culture=neutral, PublicKeyToken=null konnte nicht
geladen werden.

Translated by me:

Runtime exception: System.TypeLoadException - The Typ
System.Web.UI.WebControls.Label in the Assembly DynamicControlsAdd,
Version=1.0.1381.35345, Culture=neutral, PublicKeyToken=null could not be
loaded.

Thank you for your help. I greatly appreciate your effort.

Best greetings from Germany.

Daniel

"Jacob Yang [MSFT]" <jiany@dotnet.itags.org.online.microsoft.com> schrieb im Newsbeitrag
news:nBtZG8ikDHA.1544@dotnet.itags.org.cpmsftngxa06.phx.gbl...
> Hi Daniel,
> I have done a lot of research regarding this issue. Please try the
> following code.
> Dim ctl As System.Web.UI.WebControls.Label
> Try
> Dim MyAssembly As [Assembly]
> Dim SampleAssembly As [Assembly]
> Dim Resource As String
> ' Load the assembly by providing the type name.
> ' NOTE: Please change the Version, Culture and PublicKeyToken
> appropriately.
> SampleAssembly = MyAssembly.Load("System.Web,
> Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
> ctl =
Activator.CreateInstance(SampleAssembly.GetType("System.Web.UI.WebControls.L
> abel"))
> ctl.ID = "my1"
> ctl.Height = New Unit(200)
> ctl.Width = New Unit(400)
>
> ctl.Text = "test for Activator.CreateInstance"
> ctl.Visible = True
> Page.Controls.Add(ctl)
> Catch ex As Exception
> Dim temp As System.String = ex.Message
> Response.Write(temp)
> End Try
> Does it answer your question? If I have misunderstood your concern, please
> feel free to let me know.
> Best regards,
> Jacob Yang
> Microsoft Online Partner Support
> Get Secure! C www.microsoft.com/security
> This posting is provided "as is" with no warranties and confers no rights.Hi Daniel,

Firstly, I want to explain to you why Type.GetType("System.Int32") worked
fine. It is because that GetType searches in the calling object's assembly
first, then in the mscorlib.dll assembly. Since System.Int32 was defined in
the mscorlib.assembly, Type.GetType of course succeeds. However, for any
other objects defined outside the mscorlib assembly, it will fail, unless
we provide the full qualified type name to the Type.GetType method, for
example, the code below should work,

Dim myType1 As Type = Type.GetType("System.Web.UI.WebControls.Label,
System.Web, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a", True)
Response.Write("The 'Fullname' is " + myType2.FullName)

As for the way I provided in my previous reply, I will explain more on the
code here. The line of SampleAssembly = MyAssembly.Load("System.Web,
Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
means to load an assembly dynamically into memory. Here MyAssembly is a
variable that presents an object of System.Reflection.Assembly class. In
fact, we can change the code above as follows,

SampleAssembly = [Assembly].Load("System.Web, Version=1.0.5000.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")

The static Load method returns the assembly just loaded for later use.
Here, we store the returned assembly handle to the variable of
SampleAssembly. Then we can get any type defined in the System.Web assembly
via the SampleAssembly variable.

ctl =
Activator.CreateInstance(SampleAssembly.GetType("System.Web.UI.WebControls.L
abel"))

I hope that the information above is clear. If I have misunderstood your
concern, please feel free to let me know.

Best regards,

Jacob Yang
Microsoft Online Partner Support
Get Secure! C www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

0 comments:

Post a Comment