私の ASP.Net MVC ページでは、列ヘッダーをクリックしてその列で並べ替えることができますが、これには aspx の "マジック ストリング" が含まれており、実行時に問題が発生する可能性があります。sort by に渡された値が有効かどうかを実行時に確認しようとしています。すべてのエンティティが継承する基本クラスがあります。
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
Patient.FirstName による訪問の並べ替えは正常に機能し、プロパティは再帰的に検出されますが、Patient.PatientType に基づいて訪問を並べ替えようとすると、PatientType プロパティが見つかりません。IsValidSearchProperty は最初に VisitEntity から呼び出され、Patient プロパティを検索し、PatientEntity 型として表示されますが、このメソッドが InvokeMember を使用して自分自身を再帰的に呼び出す場合 (これは、プロパティ Type を使用してそれを呼び出そうとする方法です) 、2 番目の呼び出しでは、GetType(T) はタイプ PersonEntity であり、PatientType を持っていません。これを行う方法に関する提案は、ネストされた呼び出しの Type を正しく解決しますか?
このメソッドは次のように呼び出されます。
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」のようなものになります。