Questions › Why am I getting Expression Expected?
d.c Asked

This is my simple CodeFile vb code for a username and password login form with a redirect to different 'members area' pages:

Public Class MyPage
Inherits Page
Private Structure Cred
    Public Username As String
    Public Password As String
    Public RedirectUrl As String
    Public Sub New(un As String, pw As String, Optional ru As String = "/admin/default.aspx")
        Username = un
        Password = pw
        RedirectUrl = ru
    End Sub
End Structure

Private ReadOnly _credentials As System.Collections.Generic.IEnumerable(Of Cred) =  New Cred(){New Cred("userone", "passwordone"), New Cred("usertwo", "passwordtwo"), New Cred("userthree", "passwordthree", "/admin/custom.aspx")}

Public Sub Page_Load(sender As Object, e As EventArgs)
    Dim user = _credentials.SingleOrDefault(Function(x) x.Username = UserName.Text AndAlso x.Password = Password.Text)
    If user IsNot Nothing Then
        Session("Admin") = True
        Response.Redirect(user.RedirectUrl)
    Else
        Session("Admin") = False
        LtlLogin.Text = "<p>Sorry, you have provided incorrect login details.</p>"
    End If
End Sub
End Class

It's on the line:

Dim user = _credentials.SingleOrDefault(Function(x) x.Username = UserName.Text AndAlso x.Password = Password.Text)

Thanks very much.

David.

Comments :
Plutonix replied

obligatory warning about storing passwords as plaintext: dont

d.c replied

@Plutonix I am aware, thanks, but I'm just new to VB so taking it slow :)

shadow replied

Read about Classes and Structures.


1 Answers :
shadow answered

The problem is that you are using structure against class for Cred. Be aware that structures are value types and classes are reference types.

So:

Dim user = _credentials.SingleOrDefault(Function(x) x.Username = UserName.Text AndAlso x.Password = Password.Text)

always return a structure (when nothing found then the members of the structure gets their default values).

You cannot compare a structure to Nothing as ti is not a reference type.

Change structure to class and you will be fine.

Or change the check with:

If Not user.Equals(New Cred) Then

Check this

UPDATE with examples

Class Cred

Imports System.Linq

Module StartupModule

    Private ReadOnly _credentials As System.Collections.Generic.IEnumerable(Of Cred) = New Cred() {
        New Cred("userone", "passwordone"),
        New Cred("usertwo", "passwordtwo"),
        New Cred("userthree", "passwordthree", "/admin/custom.aspx")}

    Sub Main()
        Dim userName As String = ""
        Dim password As String = ""

        Dim crd = _credentials.Where(Function(x) x.Username = userName AndAlso x.Password = password).SingleOrDefault

        If crd Is Nothing Then
            Console.WriteLine("user is nothing")
        Else
            Console.WriteLine("user is something")
        End If


        Console.ReadLine()
    End Sub

    Private Class Cred
        Public Username As String
        Public Password As String
        Public RedirectUrl As String
        Public Sub New(un As String, pw As String, Optional ru As String = "/admin/default.aspx")
            Username = un
            Password = pw
            RedirectUrl = ru
        End Sub
    End Class


End Module

Structure Cred

Imports System.Linq

Module StartupModule

    Private ReadOnly _credentials As System.Collections.Generic.IEnumerable(Of Cred) = New Cred() {
        New Cred("userone", "passwordone"),
        New Cred("usertwo", "passwordtwo"),
        New Cred("userthree", "passwordthree", "/admin/custom.aspx")}

    Sub Main()
        Dim userName As String = ""
        Dim password As String = ""

        Dim crd = _credentials.Where(Function(x) x.Username = userName AndAlso x.Password = password).SingleOrDefault

        If crd.Equals(New Cred) Then
            Console.WriteLine("user is nothing")
        Else
            Console.WriteLine("user is something")
        End If


        Console.ReadLine()
    End Sub

    Private Structure Cred
        Public Username As String
        Public Password As String
        Public RedirectUrl As String
        Public Sub New(un As String, pw As String, Optional ru As String = "/admin/default.aspx")
            Username = un
            Password = pw
            RedirectUrl = ru
        End Sub
    End Structure


End Module
d.c replied
Sorry I am new to this, so if I change 'Structure' to 'Class' and add your new line of code after that line, it will work will it? Thanks for your help here.;
shadow replied
I believe that if you change Structure Cred to Class Cred you are ready. I guess that `UserName.Text' is a text box or something.;
d.c replied
Had to change end class from end structure as well, but I still get Expression Expected on that line. Any ideas what's wrong here. Yes Username.Text and Password.Text are asp:TextBox. Thanks!;
shadow replied
I updated my answer with both class and structure. They both works fine. Take a look.;
shadow replied
I also always use Option Explicit:On and Option Strict: On;