Reflection Object dumper.
Reflection ObjectDumper is extremely useful in two case:
- (1) if you don't know location of needed properties in object hierarchy (for example I search Win32 windows class by this object dumper in this program How to SendText to specific field in another application by Win32 API
- (2) If you program placed in hosting and you don't have opportunity to connect debugger to it. This is most common case of development and debugging payment gateways or authentication with external services, where right domain of your program have to present. In screen below I attach this ObjectDumper debugger to my new project programmer.expert
This is a code to test call my ObjectDumper.
1: Public Class Dump
2: Inherits System.Web.UI.Page
3: Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
4: If Not IsPostBack Then
5: Dim D as New ObjectDumper
6: Dim Str1 As String = D.Dump(1, Request)
7: Label1.Text = Str1.Replace(vbCrLf, "<br>")
8: End If
9: End Sub
10: End Class
And this is code of My ObjectDumper.
1: Imports System.IO
2: Imports System.Reflection
3: Imports System.Text
4: Imports System.Text.RegularExpressions
5:
6: Public Class ObjectDumper
7:
8: Private Log As TextWriter
9: Private Pos As Integer
10: Private Level As Integer
11: Private Depth As Integer
12: Private Methods As ArrayList
13:
14: Public Sub New()
15: Methods = New ArrayList
16: End Sub
17:
18: Public Sub Dump(ByVal Element As Object, Optional ByVal Depth As Integer = 0)
19: Dump(Element, Depth, Console.Out)
20: End Sub
21:
22: Public Sub Dump(ByVal Element As Object, ByVal Depth As Integer, ByVal Log1 As TextWriter)
23: Me.Depth = Depth
24: Methods = New ArrayList
25: Log = Log1 'перепрописали консолью или параметром
26: Writeobject(Nothing, Element)
27: End Sub
28:
29: Public Function Dump(ByVal Depth As Integer, ByVal Element As Object) As String
30: Me.Depth = Depth
31: Methods = New ArrayList
32: Dim Log1 = New IO.StreamWriter(New IO.MemoryStream())
33: Log = Log1
34: Writeobject(Nothing, Element)
35: Log1.Flush()
36: Log1.BaseStream.Position = 0
37: Dim Str1 As String
38: Using Sr = New IO.StreamReader(Log1.BaseStream, Encoding.UTF8)
39: Str1 = Sr.ReadToEnd()
40: End Using
41: Return Str1
42: End Function
43:
44: Private Sub GetOrderedMethod()
45: If Methods.Count > 0 Then
46: Methods.Sort()
47: Writeline()
48: WriteStr(" Method:")
49: Writeline()
50: For i As Integer = 0 To Methods.Count - 1
51: WriteStr(Methods(i).ToString & "()")
52: Writeline()
53: Next
54: End If
55: End Sub
56:
57: Private Sub WriteMethod(ByVal S As String)
58: If Not Methods.Contains(S) Then
59: Methods.Add(S)
60: End If
61: End Sub
62:
63: Private Sub WriteStr(ByVal S As String)
64: If S IsNot Nothing Then
65: Log.Write(S)
66: Pos += S.Length
67: End If
68: End Sub
69:
70: Private Sub Writeindent()
71: For I As Integer = 0 To Level - 1
72: Log.Write(" ")
73: Next
74: End Sub
75:
76: Private Sub Writeline()
77: Log.WriteLine()
78: Pos = 0
79: End Sub
80:
81: Private Sub Writetab()
82: WriteStr(" ")
83:
84: While Pos Mod 8 <> 0
85: WriteStr(" ")
86: End While
87: End Sub
88:
89: Private Sub WriteValue(ByVal O As Object)
90: If O Is Nothing Then
91: WriteStr("Null")
92: ElseIf TypeOf O Is DateTime Then
93: WriteStr((CDate(O)).ToShortDateString())
94: ElseIf TypeOf O Is ValueType OrElse TypeOf O Is String Then
95: WriteStr(O.ToString())
96: ElseIf TypeOf O Is IEnumerable Then
97: WriteStr("...")
98: Else
99: WriteStr("{ }")
100: End If
101: End Sub
102:
103: Private Sub WriteHex(ByVal buffer As Byte())
104: Dim Len As Integer = buffer.Length
105: If Len > 0 Then
106: Dim Str1 As New StringBuilder(Len * 2)
107: For i = 0 To Len - 1
108: Str1.AppendFormat(String.Format("{0:x2}", buffer(i)))
109: Next
110: WriteStr(String.Format("({0:D4})", Len) & Str1.ToString)
111: WriteStr(" ")
112: WriteStr(Regex.Replace(Encoding.ASCII.GetString(buffer, 0, Len), "[^\x20-\x7F]", ".").Replace("?", "."))
113: End If
114: End Sub
115:
116: Private Sub Writeobject(ByVal Prefix As String, ByVal Element As Object)
117: If Element Is Nothing OrElse TypeOf Element Is ValueType OrElse TypeOf Element Is String Then
118: Writeindent()
119: WriteStr(Prefix)
120: WriteValue(Element)
121: Writeline()
122: Else
123: Dim Enumerableelement As IEnumerable = TryCast(Element, IEnumerable)
124:
125: If Enumerableelement IsNot Nothing Then
126:
127: For Each Item As Object In Enumerableelement
128:
129: If TypeOf Item Is IEnumerable AndAlso Not (TypeOf Item Is String) Then
130: Writeindent()
131: WriteStr(Prefix)
132: WriteStr("...")
133: Writeline()
134:
135: If Level < Depth Then
136: Level += 1
137: Writeobject(Prefix, Item)
138: Level -= 1
139: End If
140: Else
141: Writeobject(Prefix, Item)
142: End If
143: Next
144: Else
145: Dim Members As MemberInfo() = Element.[GetType]().GetMembers(BindingFlags.[Public] Or BindingFlags.Instance)
146: Writeindent()
147: WriteStr(Prefix)
148: Dim Propwritten As Boolean = False
149:
150: For Each M As MemberInfo In Members
151: Dim F As FieldInfo = TryCast(M, FieldInfo)
152: Dim P As PropertyInfo = TryCast(M, PropertyInfo)
153:
154: If F IsNot Nothing OrElse P IsNot Nothing Then
155:
156: If Propwritten Then
157: Writetab()
158: Else
159: Propwritten = True
160: End If
161:
162: WriteStr(vbCrLf & M.Name)
163: WriteStr("=")
164: Dim T As Type = If(F IsNot Nothing, F.FieldType, P.PropertyType)
165:
166: If T.IsValueType OrElse T = GetType(String) Then
167: If F IsNot Nothing Then
168: Try
169: WriteValue(F.GetValue(Element))
170: Catch Ex As Exception
171: WriteValue("{Error:" & Ex.Message & "}")
172: End Try
173: Else
174: Try
175: WriteValue(P.GetValue(Element, Nothing))
176: Catch Ex As Exception
177: WriteValue("{Error:" & Ex.Message & "}")
178: End Try
179:
180: End If
181: Else
182:
183: If GetType(IEnumerable).IsAssignableFrom(T) Then
184: WriteStr("...")
185: Else
186: WriteStr("{ }")
187: End If
188: End If
189: End If
190: Next
191:
192: If Propwritten Then Writeline()
193:
194: If Level < Depth Then
195:
196: For Each M As MemberInfo In Members
197:
198: Dim F As FieldInfo = TryCast(M, FieldInfo)
199: Dim P As PropertyInfo = TryCast(M, PropertyInfo)
200:
201: If F IsNot Nothing OrElse P IsNot Nothing Then
202: Dim T As Type = If(F IsNot Nothing, F.FieldType, P.PropertyType)
203:
204: If Not (T.IsValueType OrElse T = GetType(String)) Then
205:
206: Dim Value As Object
207: If F IsNot Nothing Then
208: Try
209: Value = F.GetValue(Element)
210: Catch Ex As Exception
211: WriteValue("{Error:" & Ex.Message & "}")
212: End Try
213:
214: Else
215: Try
216: Value = P.GetValue(Element, Nothing)
217: Catch Ex As Exception
218: WriteValue("{Error:" & Ex.Message & "}")
219: End Try
220:
221: End If
222:
223: If Value IsNot Nothing Then
224: Level += 1
225: Writeobject(M.Name & ": ", Value)
226: Level -= 1
227: End If
228: End If
229: Else
230: WriteMethod(M.Name)
231: End If
232: Next
233: GetOrderedMethod()
234: Methods.Clear()
235: End If
236: End If
237: End If
238: End Sub
239:
240:
241: End Class
Other useful application of reflection technology you can see in page Аналіз MVC-сайту за допомогою System.Reflection and alternative way to dump objects with NewtonJson serialiser - see page Customize Newtonsoft.Json Serializer/Deserializer to convert Javascript Datetime and Number to .NET datatype..
Comments (
)
<00>
<01>
<02>
<03>
<04>
<05>
<06>
<07>
<08>
<09>
<10>
<11>
<12>
<13>
<14>
<15>
<16>
<17>
<18>
<19>
<20>
<21>
<22>
<23>
Link to this page:
//www.vb-net.com/ObjectDumper/index.htm
<SITEMAP> <MVC> <ASP> <NET> <DATA> <KIOSK> <FLEX> <SQL> <NOTES> <LINUX> <MONO> <FREEWARE> <DOCS> <ENG> <CHAT ME> <ABOUT ME> < THANKS ME> |