在我的ASP.Net MVC页面中,我可以点击列标题按该列排序,但这涉及到aspx中的“魔法字符串”,可能会导致运行时问题。我正在尝试在运行时检查排序所传递的值是否有效。我有一个所有实体都继承自的基类:
Public MustInherit Class BaseEntity(Of T)
'Some Property and method definitions...'
Public Shared Function IsValidSearchProperty(name As String) As Boolean
Dim rootPart As String = name
Dim nested As Boolean = False
If rootPart.Contains(".") Then
rootPart = rootPart.Split("."c)(0)
nested = True
End If
Dim properties As PropertyInfo() = GetType(T).GetProperties()
For Each prop As PropertyInfo In properties
If prop.Name = rootPart Then
If nested Then
'This is where my issue is'
Return Convert.ToBoolean(
prop.PropertyType.InvokeMember("IsValidSearchProperty",
BindingFlags.InvokeMethod Or BindingFlags.Public Or BindingFlags.Static Or BindingFlags.FlattenHierarchy,
Nothing, Nothing, New Object() {name.Substring(name.IndexOf(".") + 1)})
)
Else
Return True
End If
End If
Next
Return False
End Function
End Class
这很好用,但如果我试图验证一个嵌套属性,它在类层次结构中超过1个层级。例如:
'Pseudocode Hierarchy
BaseEntity(of T)
PersonEntity : Inherits BaseEntity(Of PersonEntity)
Property FirstName as string
PatientEntity : Inherits PersonEntity
Property PatientType as int
VisitEntity : Inherits BaseEntity(Of VisitEntity)
Property Patient as PatientEntity
按病人名字排序的拜访记录很好,属性会被递归地找到,但当我尝试根据病人类型对拜访记录进行排序时,它无法找到PatientType属性。IsValidSearchProperty最初是从VisitEntity调用的,该实体会查找Patient属性,它甚至显示为PatientEntity类型,但当该方法使用InvokeMember递归调用自身(这就是我使用属性类型调用它的方式)时,在第二次调用中,GetType(T)的类型为PersonEntity,这个类型没有PatientType属性。有什么建议可以使嵌套调用正确解析类型?
这个方法将像这样被调用:
VisitEntity.IsValidSearchProperty("Patient.FirstName")
VisitEntity.IsValidSearchProperty("Patient.PatientType") '* This one doesn't work
PatientEntity.IsValidSearchProperty("PatientType")
PatientEntity.IsValidSearchProperty("FirstName")
更新
以下是我如何使用这个功能:
Dim sorts() As String = SortExpression.Split(";")
For Each sort As String In sorts
Dim sortParts() As String = sort.Split(" ")
If VisitEntity.IsValidSearchProperty(sortParts(0)) Then
If sortParts(1).ToLower = "true" Then
visits = visits.OrderBy(Of VisitEntity)(sortParts(0).ToString(), SortDirection.Ascending)
Else
visits = visits.OrderBy(Of VisitEntity)(sortParts(0).ToString(), SortDirection.Descending)
End If
Else
_log.WarnFormat("Found invalid sort property {0}", sortParts(0))
End If
Next
SortExpression将类似于“Patient.PatientType True;Patient.FirstName True”
,意思是按照患者类型和名字进行排序。