Список (из T) не сотрудничает с For Each ... Следующее утверждение - PullRequest
0 голосов
/ 23 июня 2018

Мне трудно понять, почему именно это происходит.

(пока я не получу права SQL от моего работодателя) Я занимаюсь разработкой программы, которая требует аутентификацию, поэтому я использую документ XML и читаю его с помощью утилиты XDocument. Все загружается в коллекцию пользователей правильно. Коллекция определяется следующим образом внутри класса с именем UserDatabaseManager:

коллекция:

Private UserCollection As New List(Of User)

родительский элемент UserCollection определяется как:

Public UserDatabaseController As New UserDatabaseManager()

Вот класс пользователя:

Public Class User
    'CONSTANTS ----------------------------
    Public Enum RoleCode
        BasicQAAgent = 0
        QAAdministrator = 1
        ITadmin = 5
    End Enum

    'VARIABLES ----------------------------
    Dim uname As String = ""
    Dim fname As String = ""
    Dim pass As String = ""
    Dim userrole As RoleCode = 0
    Dim idnumber As Integer = 0
    Dim createDate As String = ""
    Shared Function SerializeUserFromXMLNode(ByVal XMLelement As XElement) As User
        With XMLelement
            Return New User(.@name, .<fullname>.Value, .<creationday>.Value, .<password>.Value, .<role>.Value)
        End With
    End Function

    Public Sub New(ByVal Name As String, ByVal FullName As String, ByVal CreationDay As String, ByVal PassHash As String, ByVal Role As RoleCode)
        fname = FullName : uname = Name : createDate = CreationDay : pass = PassHash : userrole = Role
    End Sub
    Public ReadOnly Property UserName As String
        Get
            Return uname
        End Get
    End Property
    Public ReadOnly Property FullName As String
        Get
            Return fname
        End Get
    End Property
    Public ReadOnly Property UserRoleCode As RoleCode
        Get
            Return userrole
        End Get
    End Property
    Public ReadOnly Property UserIDNumber As Integer
        Get
             Return idnumber
        End Get
    End Property
    Public ReadOnly Property PasswordMD5Hash As String
        Get
            Return pass
        End Get
    End Property
    Public ReadOnly Property CreationDate As Date
        Get
            Return createDate
        End Get
    End Property
End Class

У меня есть собственный пользователь. Точки останова подтвердили, что мой пользователь вместе со всеми другими записями были успешно загружены из XDocument. Я могу сделать:

UserCollection.Item(0)

и мой класс пользователя будет возвращен (я знаю, что у меня индекс 0 в xdocument).

Теперь. Что, если я хочу найти пользователя с помощью другого поля?

У меня есть функция в классе менеджера базы данных пользователя (родительский класс коллекции пользователей, класс пользователя и инструмент XDocument), который проходит через пользователей, находит пользователя, который совпадает с именем, и возвращает экземпляр пользователя обратно на вызов функции:

Public Function GetUserByName(ByVal name As String) As User
    For Each usr As User In UserCollection
        If usr.UserName = name Then
            Return usr
        End If
    Next
    Return Nothing
End Function

Ничего ВСЕГДА возвращается, фактически, точка останова на "If usr.Username ..." подтвердила, что оператор ForEach даже не выполняет цикл!

Таким образом, в основном конечный результат - NullObjectReference с экрана входа в систему. Вот код, который вызывает GetUserByName в форме экрана входа в систему:

Private Sub Btn_login_Click(sender As Object, e As EventArgs) Handles btn_login.Click
    DisableLoginElements() 'custom sub
    'try login
    'Try
    Dim inputUsr As String = tbox_Username.Text : Dim inputPass As String = CalculateMD5FromString(tbox_Password.Text)
    tbox_Password.Clear()
    If mainMDI.UserDatabaseController.GetUserByName(inputUsr) IsNot Nothing Then 'HIGHTODO: FIX NULLOBJECTREF FROM USER SEARCH.
        'crosscheck the password provided calculates same MD5 hash as MD5 hash stored in DB. if not, throw MD5calculationVarianceEx Exception
        If mainMDI.UserDatabaseController.GetUserByName(inputUsr).PasswordMD5Hash = inputPass Then
            mainMDI.initializeMainMDIwithUser(mainMDI.UserDatabaseController.GetUserByName(inputUsr)) 'authentication success!
        Else
            Throw MD5calculationVarianceEx 'Password does not match
        End If
    Else
        Throw UserNotFoundEx 'user was not found 
    End If
    'Catch ex As Exception 'an error occured, determine error
    'MsgBox(ex.Message, MsgBoxStyle.Critical, "Login Error: QA Commander")
    'EnableLoginElements()
    'End Try
End Sub

Где вы видите комментарий HIGHTODO, это где ничего не возвращается. Я закомментировал оператор Try для целей отладки.

ПОЖАЛУЙСТА, ПОМОГИТЕ МНЕ ПОИСКУ В СПИСКЕ (T) СОБСТВЕННОСТИ В ОБЪЕКТЕ, КОТОРЫЙ 'T' ПРЕДСТАВЛЯЕТ !!

Редактировать: вот копии XML и UserDatabaseManager в полном объеме:

Менеджер пользовательских баз данных:

Imports System.Collections.ObjectModel
Imports Microsoft

Public Class UserDatabaseManager

Public ReadOnly UserDatabaseManagerVersion As String = "1.0"

Private ReadOnly DBManager As Integer 'User ID Number of the database administrator
Private Company As String
Private Department As String

Private UserCollectionIndex As New Specialized.StringCollection
Public UserCollection As New List(Of User)

Dim xmlMgr As XDocument


Public Sub New(ByVal Optional databaseXMLPath As String = "")
    If Not databaseXMLPath = "" Then
        'Load datasheet from location
        xmlMgr = XDocument.Load(databaseXMLPath)
        If Not xmlMgr.<UserDB>.<version>.@value = UserDatabaseManagerVersion Then 'User Database is outdated.
            Throw UserDBfileVersionMismatchEX
        End If
        DBManager = xmlMgr.<UserDB>.<dbAdministrator>.@value
        Company = xmlMgr.<UserDB>.<company>.@value
        Department = xmlMgr.<UserDB>.<department>.@value
        Dim usersInDB As IEnumerable(Of XElement) = xmlMgr.Descendants("user")
        For Each elm As XElement In usersInDB
            Dim foundName As String = elm.@name
            Dim userEntry As UserDatabaseManager.User = New User(elm.@name, elm.<fullname>.Value, elm.<creationdate>.Value,
                                                                 elm.<password>.Value, elm.<role>.Value)
            UserCollection.Add(User.SerializeUserFromXMLNode(elm))
        Next
    Else
        'create empty instance
    End If
    'get metadeta from XDocument

End Sub

Public Function GetUserByName(ByVal name As String) As User
    For Each usr As User In UserCollection
        If usr.UserName = name Then
            Return usr
        End If
    Next
    Return Nothing
End Function
Private Function GetUserByID(ByVal ID As Integer) As User
    For Each usr As User In UserCollection
        If usr.UserIDNumber = ID Then
            Return usr : Exit Function
        End If
    Next
    Return Nothing
End Function
Public Class User
    'CONSTANTS ----------------------------
    Public Enum RoleCode
        BasicQAAgent = 0
        QAAdministrator = 1
        ITadmin = 5
    End Enum

    'VARIABLES ----------------------------
    Dim uname As String = ""
    Dim fname As String = ""
    Dim pass As String = ""
    Dim userrole As RoleCode = 0
    Dim idnumber As Integer = 0
    Dim createDate As String = ""
    Shared Function SerializeUserFromXMLNode(ByVal XMLelement As XElement) As User
        With XMLelement
            Return New User(.@name, .<fullname>.Value, .<creationday>.Value, .<password>.Value, .<role>.Value)
        End With
    End Function

    Public Sub New(ByVal Name As String, ByVal FullName As String, ByVal CreationDay As String, ByVal PassHash As String, ByVal Role As RoleCode)
        fname = FullName : uname = Name : createDate = CreationDay : pass = PassHash : userrole = Role
    End Sub

    Public ReadOnly Property UserName As String
        Get
            Return uname
        End Get
    End Property
    Public ReadOnly Property FullName As String
        Get
            Return fname
        End Get
    End Property
    Public ReadOnly Property UserRoleCode As RoleCode
        Get
            Return userrole
        End Get
    End Property
    Public ReadOnly Property UserIDNumber As Integer
        Get
            Return idnumber
        End Get
    End Property
    Public ReadOnly Property PasswordMD5Hash As String
        Get
            Return pass
        End Get
    End Property
    Public ReadOnly Property CreationDate As Date
        Get
            Return createDate
        End Get
    End Property
End Class

База данных XML:

<UserDB>
  <version value="1.0" />
  <lastEditedDate value="6/21/2018 3:23PM" />
  <dbAdministrator value="0000001" />
  <company value="Anomaly Squared" />
  <department value ="Quality Assurance" />

  <DBPreferences>
    <DefaultPassword>Password18</DefaultPassword>
    <DefaultPasswordHash>E527FABE14F0F6C0C7AD35886614BEAE</DefaultPasswordHash>
    <ForcePassChangeIfDefault>True</ForcePassChangeIfDefault>
  </DBPreferences>



  <QAAgents>
    <user name="mwendel">
      <userid>0000001</userid>
      <password>8814CD66C7804638B4CCE9233CBF4987</password>
      <fullname>Matthew Wendel</fullname>
      <role>5</role>
      <creationdate>6/23/2018</creationdate>
      <activityHistory>
        <action kind="selfCreatedAccount" date="6/23/2018" result="0x0" />
      </activityHistory>
    </user>

    <user name="jappleseed">
      <userid>0185432</userid>
      <password>E527FABE14F0F6C0C7AD35886614BEAE</password>
      <fullname>Johnny Appleseed</fullname>
      <role>1</role>
      <creationdate>6/23/2018</creationdate>
      <activityHistory>
        <result kind="ITCreatedAccount" date="6/23/2018" result="0x0" />
      </activityHistory>
    </user>
  </QAAgents>


</UserDB>
      User role Definitions
        0 = Basic QA Agent. 
          Ability to:
            • create new evaluations
            • view completed evaluations
            • add employees

        1 = QA Administrator
          Same as basic, but in addition:
            • add/create QA Agent accounts.
            • Can edit previous evaluations.
            • Produce evaluations of Basic QA Agents
            • add/edit/remove campaigns

        5 = IT/Systems Administrator
            Full atonomy to edit and maintain all elements of the system.

1 Ответ

0 голосов
/ 25 июня 2018

Ничего себе.Я действительно могу ответить на свой собственный вопрос !!!!

Так что функция GetUserByName при вызове ссылалась на список (пользователя), который был в экземпляре по умолчанию для UserDatabaseManager, INSTEADодин я объявил как UserDatabaseController!Использование ключевого слова Me ОЧЕНЬ важно, поскольку оно гарантирует, что функция указывает на экземпляр объекта, который вы объявили, а НЕ на пустую коллекцию по умолчанию.Вот обновленная функция, и все работает как есть:

Public Function GetUserByName(ByVal u_name As String) As User
    For Each usr As User In Me.UserCollection
        If usr.UserName = u_name Then
            Return usr
        End If
    Next
    Return Nothing
End Function

Идентификатор Me в "... User in Me.UserCollection .." в основном исправил это.Спасибо всем за помощь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...