I have a set of classes, whose properties have data annotations on them. Some of these class properties are of primitive types (and by primitive, I also mean types such as string, double, datetime etc), while others are properties of a custom type.
I would like to be able to iterate through the properties of a class and the properties of the nested objects and pull out the attributes of each property. I've played around with reflection and my code works fine, if the class under consideration has only one property of a custom type. However when a class has multiple properties of a custom type and each of those properties have other custom types, I am completely lost on how I'd keep track of the objects/properties that have already been visited.
This is where I have got so far. I have seen a lot of examples on the forum, but they all have a simple nested class, where there is a maximum of one custom type per class. Below is a sample of what I am trying to get done:
Public Class Claim
<Required()>
<StringLength(5)>
Public Property ClaimNumber As String
<Required()>
Public Property Patient As Patient
<Required()>
Public Property Invoice As Invoice
End Class
Public Class Patient
<Required()>
<StringLength(5)>
Public Property MedicareNumber As String
<Required()>
Public Property Name As String
<Required()>
Public Property Address As Address
End Class
Public Class Address
Public Property Suburb As String
Public Property City As String
End Class
Public Class Invoice
<Required()>
Public Property InvoiceNumber As String
<Required()>
Public Property Procedure As String
End Class
Public Shared Function Validate(ByVal ObjectToValidate As Object) As List(Of String)
Dim ErrorList As New List(Of String)
If ObjectToValidate IsNot Nothing Then
Dim Properties() As PropertyInfo = ObjectToValidate.GetType().GetProperties()
For Each ClassProperty As PropertyInfo In Properties
Select Case ClassProperty.PropertyType.FullName.Split(".")(0)
Case "System"
Dim attributes() As ValidationAttribute = ClassProperty.GetCustomAttributes(GetType(ValidationAttribute), False)
For Each Attribute As ValidationAttribute In attributes
If Not Attribute.IsValid(ClassProperty.GetValue(ObjectToValidate, Nothing)) Then
ErrorList.Add("Attribute Error Message")
End If
Next
Case Else
Validate(ClassProperty.GetValue(ObjectToValidate, Nothing))
**** ‘At this point I need a mechanism to keep track of the parent of ClassProperty and also mark ClassProperty as visited, so that I am able to iterate through the other properties of the parent (ObjectToValidate), without revisiting ClassProperty again.**
End Select
Next
End If
Return Nothing
End Function
The most straightforward (and probably easiest) way to approach this is to keep a Dictionary of class property attributes keyed by class name.
If I were approaching this, I would probably create a class to hold the property attributes:
Public Class PropertyAttribute
Public PropertyName As String
Public PropertyTypeName As String
Public Required As Boolean
Public StringLength As Integer
End Class
Then create a class to hold information about each class' properties:
Public Class ClassAttributes
Public ClassName As String
' You could also use a dictionary here to key properties by name
Public PropertyAttributes As New List(Of PropertyAttribute)
End Class
Finally, create a dictionary of ClassAttributes to keep track of which custom classes you have already processed:
Public ProcessedClasses As New Dictonary(Of String, ClassAttributes)
The key for the dictionary is the classname.
When you are processing the attributes through reflection, if the property type is custom, check the dictionary for the existence of the class. If it is there, you don't have to process it.
If it is not there, add a new instance to the dictionary immediately (so that nested objects of the same type are safely handled) and then process the attributes of the class.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.