Expression Expected - asp.net

Im getting a build error with the following code...
Private Property GridViewSortDirection() As String
Get
Return If(TryCast(ViewState("SortDirection"), String), "ASC")
End Get
Set(ByVal value As String)
ViewState("SortDirection") = value
End Set
End Property
It is happening on the following line...
Return If(TryCast(ViewState("SortDirection"), String), "ASC")
Error returns...
Error 11 C:\inetpub\wwwroot\TPSupport\main\UserControls\grid.ascx.vb(192): error BC30201: Expression expected.
Any Idea's
Thanks
Its a convert from c#
private string GridViewSortDirection
{
get { return ViewState["SortDirection"] as string ?? "ASC"; }
set { ViewState["SortDirection"] = value; }
}

I am not familiar with VB but use of If keyword shows that you are doing comparison between result of TryCast and "ASC",
Try this way, by using appropriate comparison operator like
Return If(TryCast(ViewState("SortDirection"), String) <> "ASC")

What compiler version are you using? I suspect that you inadvertently switched to a version of VB (< 9.0) that doesn’t yet support the conditional operator.

Related

Nullable object must have a value in IComparable.CompareTo

I have a custom class that needs to be sortable using a Nullable(of Double) property. I have defined the class, and implemented iCompare. Within my code, I thought I had placed sufficient checks for Null values, but I am suddenly seeing this error...
Nullable object must have a value.
...on this line:
Return Me.SomeDouble.Value.CompareTo(CType(obj, MatrixCellData).SomeDouble.Value)
Can anyone please explain why this is happening? I know that usually this error can be easily avoided by using Double.HasValue, which I have included. The full sample code to reproduce is below.
Namespace MyApp
Public Class MatrixCellData
Implements IComparable
Public Property SomeDouble As Nullable(Of Double)
Public Function CompareTo(obj As Object) As Integer Implements System.IComparable.CompareTo
If obj Is Nothing OrElse IsDBNull(obj) OrElse Not TypeOf (obj) Is MatrixCellData Then
Return 1
Else
If Not Me.SomeDouble.HasValue Then
Return -1
Else
Return Me.SomeDouble.Value.CompareTo(CType(obj, MatrixCellData).SomeDouble.Value)
End If
End If
End Function
End Class
End Namespace
Breaking code...
Dim lst As New List(Of MyApp.MatrixCellData)
lst.Add(New MyApp.MatrixCellData With {.SomeDouble = 75})
lst.Add(New MyApp.MatrixCellData With {.SomeDouble = 25})
lst.Add(New MyApp.MatrixCellData With {.SomeDouble = Nothing})
lst.Sort() ' Triggers error
If you don't use
If Not Me.SomeDouble.HasValue Then
Then there's no check to stop Me.SomeDouble from being equal to Nothing.
When you call the sort function on your list, you will be calling the CompareTo function at least once for each item. Effectively, the framework tries to place your last item somewhere in the ordered list the call looks similar to this:
(New MatrixCellData With {.SomeDouble = Nothing}).CompareTo(New MatrixCellData With {.SomeDouble = 25})
All the following checks are false:
If obj Is Nothing OrElse IsDBNull(obj) OrElse Not TypeOf (obj) Is MatrixCellData Then
Obj isn't Nothing, (Me.SomeDouble is Nothing)
This means your last line in the CompareTo method
Return Me.SomeDouble.Value.CompareTo(CType(obj, MatrixCellData).SomeDouble.Value)
In the case where Me.SomeDouble is Nothing, will actually be:
Return Nothing.Value.CompareTo(CType(obj, MatrixCellData).SomeDouble.Value)
Which of course doesn't make sense since Nothing does not have a 'Value' method or property.
I would re-write this as
Public Function CompareTo(obj As Object) As Integer Implements System.IComparable.CompareTo
If obj Is Nothing OrElse Not TypeOf (obj) Is MatrixCellData OrElse CType(obj, MatrixCellData).SomeDouble Is Nothing Then
Return 1
Else If Me.SomeDouble is Nothing Then
Return -1
End If
Return Me.SomeDouble.Value.CompareTo(CType(obj, MatrixCellData).SomeDouble.Value)
End Function

Understanding how Public Properties are set in VB.NET

I am trying to understand how a value in a Public property is set. There does not seem to be anything passed or any kind of lookup.
Public Shared Property IsUser() As String
Get
If HttpContext.Current.Session("IsUser") IsNot Nothing Then
Return HttpContext.Current.Session("IsUser").ToString()
Else
Return Nothing
End If
End Get
Set(value As String)
HttpContext.Current.Session("IsUser") = value
End Set
End Property
I have tried searching for the ClassName i.e. UserSession.IsUser = and also the only place the session value is set is in the property. HttpContext.Current.Session("IsUser") = value
What do I need to understand better.. I mean at the end of the day the User has to be True or False so where is the Lookup or passed parameter?

VB.net CA1062 validate parameter

Working on an old .net 3.5 vb web application
Getting over 1000 warnings on public property methods such as the following
CA1062 : Microsoft.Design : In externally visible method 'TheClass.TheMethod.Set(String)', validate parameter 'value' before using it.
Original:
Public Property DealerBMRName() As String
Get
Return hdBMRName.Value
End Get
Set(ByVal value As String)
hdBMRName.Value = value.Trim()
End Set
End Property
modified yet still throwing the error:
Public Property DealerBMRName() As String
Get
Return hdBMRName.Value
End Get
Set(ByVal value As String)
If value Is Nothing Then
hdBMRName.Value = ""
Else
hdBMRName.Value = CStr(value)
End If
End Set
End Property
Pretty sure I am following MSDN suggested workaround:
http://msdn.microsoft.com/en-us/library/ms182182(v=vs.100).aspx
Any ideas what I might be missing apart from the fact that the code itself is ugly?
I can't remove the error even with something as basic as:
Set(ByVal value As String)
hdBMRName.Value = "SomeValue"
End Set
Using VS2010 and resharper.
The issue resolved itself when I fixed a bad line entry in my web.config. It had nothing to do with the error but may have been throwing the issue.
PS: I needed to use .Value as the object is an asp:hiddenField.

Testing object instance returns "Conversion from string "" to type 'Boolean' is not valid."

I am trying to test for an instance of an object, but VB pukes and throws the exception:
Conversion from string "" to type 'Boolean' is not valid.
Here is how I am testing:
Dim objGA As New Gatherer.Gathered("", -1)
objGA = objGatherers(idx)
If Not objGA Is Nothing Then <--exception occurs here
' Do something here
End If
If I do not do this check then I get:
Object reference not set to an instance of an object.
I don't understand the first error given the objGA is an object not a string!
How else should I perform this test? Is there a consistent way to check?
If objGA IsNot Nothing Then
' put some code here...
End If
MSDN: IsNot Operator
try this.
try to check null object using IsDBNull(oValue) Method.
IsDBNull is inbuilt function to check null value.
Dim oValue As Object
Dim DefaultValue As Object
If IsDBNull(oValue) Then
Return DefaultValue
Else
Return oValue
End If
Try this:
Dim objGA As New Gatherer.Gathered("", -1)
Stop 'examine objGA
objGA = objGatherers(idx)
Stop 'examine objGA
At the first stop is objGA a "Gathered object"? When you type the first line does it tell you what the return type is?

How to get the value of an XML element using Linq even when empty

Please excuse my stupidity, I tend to find the traversing XML overly complicated.
I am using ASP.NET in VB.
I have an XML document which contains all the details of staff in my company...
<staff>
<staffName>Test Staff</staffName>
<staffTitle>Slave</staffTitle>
<staffDepartmentName>Finance</staffDepartmentName>
<staffOffice>London</staffOffice>
<staffEmail>t.staff#company.co.uk</staffEmail>
<staffPhone>0207 123 456</staffPhone>
<staffNotes>Working hours Mon to Thurs 9.15 - 5.15</staffNotes>
<staffBio></staffBio>
</staff>
As you can see, some nodes do not always contain data for ever member of staff; only Directors have biographies.
I access the values like this...
For Each staff In ( _
From matches In myXMLFile.Descendants("staff").Descendants("staffName") _
Where matches.Nodes(0).ToString.ToLower.Contains(LCase(search)) _
Order By matches.Value _
Select matches)
staffName = staff.Descendants("staffName").Nodes(0).ToString)
staffTitle = staff.Descendants("staffTitle").Nodes(0).ToString)
staffOffice = staff.Descendants("staffOffice").Nodes(0).ToString)
staffEmail = staff.Descendants("staffEmail").Nodes(0).ToString)
staffPhone = staff.Descendants("staffPhone").Nodes(0).ToString)
staffNotes = staff.Descendants("staffNotes").Nodes(0).ToString)
staffBio = staff.Descendants("staffBio").Nodes(0).ToString)
' Do something with that data...
Next
Once it gets to staffBio I get an error saying "Object reference not set to an instance of an object." obviously because that node does not exist.
My question is how can I assign the value to a variable even when it is empty without having to do a conditional check before each assignment?
First, myXMLFile.Descendants("staff").Descendants("staffName") is redundant. Descendants returns all the elements at any level within an XDocument or XElement. So, myXMLFile.Descendants("staffName") would give the same result.
Second, you can just use the Element property and the Value property like this:
staffBio = staff.Element("staffBio").Value
staff will only have one staffBio element, so there's no need to use the Descendants property. Value is a string, so you don't need to call Value.ToString. If the element is empty, then Value will return an empty string, which is what you're looking for!
Third, there is a much better (and I believe more straight forward) way of doing this in VB.NET. Here's a console app that demonstrates how I would do this:
Module Module1
Sub Main()
Dim myXMLFile = <allStaff>
<staff>
<staffName>Test Staff</staffName>
<staffTitle>Slave</staffTitle>
<staffDepartmentName>Finance</staffDepartmentName>
<staffOffice>London</staffOffice>
<staffEmail>t.staff#battens.co.uk</staffEmail>
<staffPhone>0207 123 456</staffPhone>
<staffNotes>Working hours Mon to Thurs 9.15 - 5.15</staffNotes>
<staffBio></staffBio>
</staff>
<staff>
<staffName>Other Staff</staffName>
<staffTitle>Master</staffTitle>
<staffDepartmentName>IT</staffDepartmentName>
<staffOffice>Oxford</staffOffice>
<staffEmail>o.staff#battens.co.uk</staffEmail>
<staffPhone>0207 123 789</staffPhone>
<staffNotes></staffNotes>
<staffBio>Some guy.</staffBio>
</staff>
</allStaff>
Dim search = "Test"
Dim searchQuery = From staff In myXMLFile...<staff> _
Where staff.<staffName>.Value.Contains(search) _
Select si = New StaffInfo With {.Name = staff.<staffName>.Value, _
.Title = staff.<staffTitle>.Value, _
.Department = staff.<staffDepartmentName>.Value, _
.Office = staff.<staffOffice>.Value, _
.Email = staff.<staffEmail>.Value, _
.Phone = staff.<staffPhone>.Value, _
.Notes = staff.<staffNotes>.Value, _
.Bio = staff.<staffBio>.Value}
For Each staff In searchQuery
Console.WriteLine("Name: {0}", staff.Name)
Console.WriteLine("Title: {0}", staff.Title)
Console.WriteLine("Department: {0}", staff.Department)
Console.WriteLine("Office: {0}", staff.Office)
Console.WriteLine("Email: {0}", staff.Email)
Console.WriteLine("Phone: {0}", staff.Phone)
Console.WriteLine("Notes: {0}", staff.Notes)
Console.WriteLine("Bio: {0}", staff.Bio)
Console.WriteLine()
Next
Console.ReadLine()
End Sub
Private Class StaffInfo
Private _name As String
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Private _title As String
Public Property Title() As String
Get
Return _title
End Get
Set(ByVal value As String)
_title = value
End Set
End Property
Private _department As String
Public Property Department() As String
Get
Return _department
End Get
Set(ByVal value As String)
_department = value
End Set
End Property
Private _office As String
Public Property Office() As String
Get
Return _office
End Get
Set(ByVal value As String)
_office = value
End Set
End Property
Private _email As String
Public Property Email() As String
Get
Return _email
End Get
Set(ByVal value As String)
_email = value
End Set
End Property
Private _phone As String
Public Property Phone() As String
Get
Return _phone
End Get
Set(ByVal value As String)
_phone = value
End Set
End Property
Private _notes As String
Public Property Notes() As String
Get
Return _notes
End Get
Set(ByVal value As String)
_notes = value
End Set
End Property
Private _bio As String
Public Property Bio() As String
Get
Return _bio
End Get
Set(ByVal value As String)
_bio = value
End Set
End Property
End Class
End Module
If you have a schema (.xsd file) for your XML, then you can import a reference to that xmlns to your VB source file, which will give you intellisense for writing your LINQ to XML queries.
(Edit: A quick way to create a schema is to open up an XML file in Visual Studio and choose Create Schema from the XML menu.)
For more information and help, please check out the "How Do I" video series on LINQ by Beth Massi.
OK think this is how to do it.
...
staffBio = staff.Descendants("staffBio").ElementAtOrDefault(0).Value.ToString)
...
Using .ElementAtOrDefault(0) instead of .Nodes(0) just returns "" if it's empty or <staffBio>whatever</staffBio> if it is not.
.Value just returns the content of the tags like "whatever" in the example above.
Is this right? Can anyone see any problems with this?

Resources