Handle DBNull in an object initializer - asp.net

In my asp.net web service, I have an object class which get data from database, but I counter the following problem when some data is null in database:
(1) If I don't handle the NULL value in database and use the code as below:
<WebMethod> _
Public Function GetCustomerDetail(ByVal sqlQuery As String) As List(Of customerInfo)
Dim detaillist = New List(Of customerInfo)()
Dim detail As customerInfo
Dim da = New SqlDataAdapter(sqlQuery, conn)
Dim dt = New DataTable()
da.Fill(dt)
For Each dr As DataRow In dt.Rows
detail = New customerInfo() With { _
.CustomerID = dr("CUSTOMER_ID"), _
.CustomerName = dr("CUSTOMER_NAME"), _
.RegisterDate = dr("REGISTER_DATE"), _
.Address = dr("ADDRESS") _
}
detaillist.Add(detail)
Next
Return detaillist
End Function
Public Class customerInfo
Public CustomerID As String = String.Empty
Public CustomerName As String = String.Empty
Public RegisterDate As String = Date.Now.ToString("dd/MM/yyyy")
Public Address As String = String.Empty
End Class
I got the error:
System.InvalidCastException: Conversion from type 'DBNull' to type 'String' is not valid.
(2) if I handle the NULL in database as below:
<WebMethod> _
Public Function GetCustomerDetail(ByVal sqlQuery As String) As List(Of customerInfo)
Dim detaillist = New List(Of customerInfo)()
Dim detail As customerInfo
Dim da = New SqlDataAdapter(sqlQuery, conn)
Dim dt = New DataTable()
da.Fill(dt)
For Each dr As DataRow In dt.Rows
detail = New customerInfo() With { _
.CustomerID = dr("CUSTOMER_ID"), _
.CustomerName = dr("CUSTOMER_NAME"), _
.RegisterDate = dr("REGISTER_DATE"), _
If dr("ADDRESS") = System.DBNull.Value Then
.Address = ""
Else
.Address = dr("ADDRESS") _
End if
}
detaillist.Add(detail)
Next
Return detaillist
End Function
Public Class customerInfo
Public CustomerID As String = String.Empty
Public CustomerName As String = String.Empty
Public RegisterDate As String = Date.Now.ToString("dd/MM/yyyy")
Public Address As String = String.Empty
End Class
I got the error:
Compiler Error Message: BC30985: Name of field or property being initialized in an object initializer must start with '.'.
I want to know how to handle the DBNull value for string and date in an object initializer.

You can use Convert.ToString
<WebMethod> _
Public Function GetCustomerDetail(ByVal sqlQuery As String) As List(Of customerInfo)
Dim detaillist = New List(Of customerInfo)()
Dim detail As customerInfo
Dim da = New SqlDataAdapter(sqlQuery, conn)
Dim dt = New DataTable()
da.Fill(dt)
For Each dr As DataRow In dt.Rows
Dim registerDate As Date
If Date.TryParse(Convert.ToString(dr("REGISTER_DATE")), registerDate ) = False Then
'Do what you need to do if the cell is not a valid date time value
End If
detail = New customerInfo() With { _
.CustomerID = Convert.ToString(dr("CUSTOMER_ID")), _
.CustomerName = Convert.ToString(dr("CUSTOMER_NAME")), _
.RegisterDate = registerDate.ToString("dd/MM/yyyy"), _
.Address = Convert.ToString(dr("ADDRESS"))
}
detaillist.Add(detail)
Next
Return detaillist
End Function
Edited based on OP's comment below.

While the other methods would work, I think a re-usable extension method with generics support would be ideal.
You can pass the work off to the extension method and check if the value is equal to the value of DBNull.Value
Public Module DataRowExtensions
<System.Runtime.CompilerServices.Extension>
Public Function GetValueOrDefault(Of TExpectedType)(dr As DataRow, propertyName As String) As TExpectedType
If DBNull.Value.Equals(dr(propertyName)) Then
Return Nothing
End If
Return DirectCast(dr(propertyName), TExpectedType)
End Function
End Module
You can see this DotNetFiddle to see it in action with various data types.
Do make note that the extension method Field<T> does exist and is similar, but it doesn't handle DBNull values.

You can't use an if statement inside an object initializer like that.
You have to instantiate the object, then set the properties in separate lines.
detail = New customerInfo()
'Then in separate lines, populate the properties individually
If dr("ADDRESS") = System.DBNull.Value Then
detail.Address = ""
Else
detail.Address = dr("ADDRESS")

Related

Function result in an array of own structure

In the Gen class file I have got this structure:
Public Structure StructElements
Public ID As Integer
Public Name As String
End Structure
An then this function:
Public Function FillElements(_param As String, count As Integer) As StructElements
Dim i As Integer = 0
Dim myConn As SqlConnection = New SqlConnection
Dim myCmd As SqlCommand
Dim myReader As SqlDataReader
myConn.ConnectionString = sc.ConfigurationManager.ConnectionStrings("sidConnectionString").ConnectionString
myCmd = myConn.CreateCommand
myCmd.CommandText = "SELECT * FROM " & _param
Select Case _param
Case = "Scopes"
Dim Scope(count) As StructElements
myConn.Open()
myReader = myCmd.ExecuteReader()
While myReader.Read
Scope(i).ID = myReader.Item(0)
Scope(i).Name = myReader.Item(1).ToString
i += 1
End While
myReader.Close()
myCmd.Dispose()
myConn.Close()
myConn.Dispose()
Return Scope
...
End Function
Then in the edit.aspx codebehind I have:
Public Class edit
...
Public istGen = New Gen()
...
Public iScopes As Integer
Public Scope(iScopes) As StructElements
...
Private Sub edit_Init(sender As Object, e As EventArgs) Handles Me.Init
...
iScopes = istGen.CountElements("Scopes") - 1
ReDim Scope(iScopes)
Scope = istGen.FillElements("Scopes", iScopes)
...
End Sub
End Class
This is the error I get:
Value of type 'Gen.StructElements()' cannot be converted to 'Gen.StructElements'.
I have figured out the problem is with the "Return Scope" of the FillElements function since it's expecting as an output a StructElements and not an array of StructElements (that's what the Scope variable is). How should I change my code in order for the function output to be an array of StructElements?
I have tried to look for an answer on the web but didn't find much. Someone was suggesting to use lists instead of arrays, but that would request to heavily refurbish my code and project, so if there is an easy way to do it I would strongly prefer it.
Thanks in advance for your support.
Regards.

Iterate through JSON array in webmethod using vb.net

I have this JSON Array of objects that represents 3 records
{"Data":[{"RecID":2383,"PrtStatus":true},{"RecID":3387,"PrtStatus":true},{"RecID":3388,"PrtStatus":true}]}
and I m trying to iterate through it. I built the following class for it
Public Class TblRegJoindata
Dim p_RecID As Integer
Dim p_status As Boolean
Public Property RecID As Integer
Get
Return p_RecID
End Get
Set(ByVal value As Integer)
p_RecID = value
End Set
End Property
Public Property PrtStatus As Boolean
Get
Return p_status
End Get
Set(ByVal value As Boolean)
p_status = value
End Set
End Property
End Class
In my web method I can access the data but can't figure out a way to loop through them and store them
<WebMethod> _
Public Function TblRegJoinUpd3(ByVal Data As List(Of TblRegJoindata))
Dim x As Integer = Data(0).RecID
End Function
What I m Trying to do is something like this, I tried to implement it but using "length" property is not allowed
For i As Integer = 0 To Data.Length - 1
cmd.Parameters.Clear()
cmd.Parameters.Add("#RecID", SqlDbType.Int).Value = Convert.ToInt32(i)
cmd.Parameters.Add("#PrtStatus", SqlDbType.Bit).Value = Boolean.Parse((i))
cmd.ExecuteNonQuery()
Next
Update
<WebMethod> _
Public Function TblRegJoinUpd3(ByVal Data As List(Of TblRegJoindata))
Dim constr As String = ConfigurationManager.ConnectionStrings("ARTSQLConStrng").ConnectionString
Using con As New SqlConnection(constr)
Using cmd As New SqlCommand("TblRegjoinUpdRec", con)
cmd.CommandType = CommandType.StoredProcedure
con.Open()
For i As Integer = 0 To Data.Count - 1
cmd.Parameters.Clear()
cmd.Parameters.Add("#RecID", SqlDbType.Int).Value = Convert.ToInt32(Data(i).RecID)
cmd.Parameters.Add("#PrtStatus", SqlDbType.Bit).Value = Boolean.Parse(Data(i).PrtStatus)
cmd.ExecuteNonQuery()
Next
con.Close()
End Using
End Using
Return (Data.Count)
Return data.count is just for test purposes
Thanks to Chetan Ranpariya
The whole working solution is below
Public Class TblRegJoindata
Dim p_RecID As Integer
Dim p_status As Boolean
Public Property RecID As Integer
Get
Return p_RecID
End Get
Set(ByVal value As Integer)
p_RecID = value
End Set
End Property
Public Property PrtStatus As Boolean
Get
Return p_status
End Get
Set(ByVal value As Boolean)
p_status = value
End Set
End Property
End Class
<WebMethod> _
Public Function TblRegJoinUpd3(ByVal Data As List(Of TblRegJoindata))
Dim constr As String = ConfigurationManager.ConnectionStrings("ARTSQLConStrng").ConnectionString
Using con As New SqlConnection(constr)
Using cmd As New SqlCommand("TblRegjoinUpdRec", con)
cmd.CommandType = CommandType.StoredProcedure
con.Open()
For i As Integer = 0 To Data.Count - 1
cmd.Parameters.Clear()
cmd.Parameters.Add("#RecID", SqlDbType.Int).Value = Convert.ToInt32(Data(i).RecID)
cmd.Parameters.Add("#PrtStatus", SqlDbType.Bit).Value = Boolean.Parse(Data(i).PrtStatus)
cmd.ExecuteNonQuery()
Next
con.Close()
End Using
End Using
Return (Data.Count)

Webservice having trouble pass back to client

I having trouble passing back the result which is multiple row getting from MS-SQL2012 to client. I have tried to google up but still not find the solution. Since I'm new in .NET and this is my first webservice, required an assistant to solve my problem or suggest any better solution.
Result need to pass back to client
Public Class Service1
Inherits System.Web.Services.WebService
Public Class Dealer
Public IDNo, ICFound, POFound As String
End Class
<WebMethod()> _
Public Function DailyCheckDealer(records As String()()) As String
Dim mylist As List(Of String()) = records.ToList()
Dim datarow As String = ""
Dim result As String = "Done"
For i As Integer = 0 To mylist.Count - 1
Dim m As String() = mylist(i)
For j As Integer = 0 To m.Length - 1
datarow += m(j) + " "
Next
Next
//Insert the array into the database.
Dim objDealer As New Dealer
Dim myConnString = System.Configuration.ConfigurationManager.AppSettings("MM_CONNECTION_STRING_iPRIS")
Dim myConnection1 = New SqlConnection(myConnString)
Dim myCommand = New SqlCommand()
myCommand.CommandType = CommandType.StoredProcedure
myCommand.Connection = myConnection1
myCommand.CommandText = "DailyCheckDealer"
myCommand.Parameters.Add("#DataRow", SqlDbType.VarChar, 8000).Value = datarow
myConnection1.Open()
myCommand.ExecuteNonQuery()
myConnection1.Close()
// Get the record(s) after processing and return it back to client
Dim myConnection2 = New SqlConnection(myConnString)
Dim objComm As New SqlCommand("Select IDNo, IDFound, POFound From DailyDealerCheck Order By IDNo", myConnection2)
myConnection2.Open()
Dim sdr As SqlDataReader = objComm.ExecuteReader()
If sdr.Read() Then
objDealer.IDNo = sdr("IDNo").ToString()
objDealer.ICFound = sdr("IDFound").ToString()
objDealer.POFound = sdr("POFound").ToString()
End If
myConnection2.Close()
Return objDealer
End Function
End Class
You're getting your data and putting it into objDealer which is an instance of type Dealer. You then actually have Return objDealer
Clrearly you want to return an instance of Dealer. However your function is declared as returning a string. That shouldn't even compile! Change the declaration to this:
<WebMethod()> _
Public Function DailyCheckDealer(records As String()()) As Dealer
That will allow it to return a Dealer not a string.
EDIT - to return more than one Dealer:
<WebMethod()> _
Public Function DailyCheckDealer(records As String()()) As List(Of Dealer)
' code left out
Dim myConnection2 = New SqlConnection(myConnString)
Dim objComm As New SqlCommand("Select IDNo, IDFound, POFound From DailyDealerCheck Order By IDNo", myConnection2)
' Create list of Dealers for return
Dim dealerList as New List(Of Dealer)
myConnection2.Open()
Dim sdr As SqlDataReader = objComm.ExecuteReader()
If sdr.Read() Then
objDealer.IDNo = sdr("IDNo").ToString()
objDealer.ICFound = sdr("IDFound").ToString()
objDealer.POFound = sdr("POFound").ToString()
' Add the latest to the list
dealerList.Add(objDealer)
End If
myConnection2.Close()
' Return list of dealers
Return dealerList
End Function

Value of type ... cannot be converted to

I keep receiving the following error whenever I try to run my code. Are there any suggestions on what may be causing me to not be able to convert? It seems as though both types are the same, so I'm a little confused on this one.
Value of type 'System.Collections.Generic.List(Of CVE)' cannot be converted to 'System.Collections.Generic.List(Of CVE)'
Error is occurring here:
Dim cveList As List(Of CVE)
cveList = CVERepository.GetInstance.ReadAllCVEs
Here's the CVERepository class:
Public Class CVERepository
Private Sub New()
End Sub
Public Shared ReadOnly Property GetInstance As CVERepository
Get
Static Instance As CVERepository = New CVERepository
Return Instance
End Get
End Property
Public Function ReadAllCVEs() As List(Of CVE)
Dim objAdapter As OleDb.OleDbDataAdapter
Dim dtCVE As New DataTable()
Dim strSQL As String
Dim strConn As String
Dim dvCVE As DataView
strConn = ConnectStringBuild()
strSQL = "Select * From CVE"
objAdapter = New OleDb.OleDbDataAdapter(strSQL, strConn)
objAdapter.Fill(dtCVE)
dvCVE = dtCVE.DefaultView
Dim cveList As New List(Of CVE)
'Put it into an object list to make it more managable.
For index = 0 To dvCVE.Count - 1
Dim cve As New CVE
cve.ID = dvCVE(index)("CVEID")
cve.PublishedDate = dvCVE(index)("PublishedDate")
cve.Availability = dvCVE(index)("Availability")
cve.CVSSScore = dvCVE(index)("CVSSScore")
cve.Confidentiality = dvCVE(index)("Confidentiality")
cve.Integrity = dvCVE(index)("Integrity")
cve.Summary = dvCVE(index)("Summary")
cveList.Add(cve)
Next
Return cveList
End Function
Public Shared Function ConnectStringBuild() As String
'Grabbing connection string from web.config
Return System.Configuration.ConfigurationManager.ConnectionStrings("CVEConnectionString").ConnectionString
End Function
End Class
Any suggestion on the error?
just a little change
Dim cveList As List(Of CVE)
cveList.AddRange(CVERepository.GetInstance.ReadAllCVEs)

Using VariantType in ASP.net

Hoping for a quick answer here.
OK, since I do a lot of single value lookups from the DB, I created a function to handle the lookup for me. It's designed to get any type of data type (string, integer, date, ...).
It works when I want to retrieve a number, but gives me an error when I want a string (InvalidCastException trying to convert a string to an integer on the line: GetValue = DR(0)).
I can't do a ctype or directcast because the datatype is unknown and varies.
Haven't tested any other data types yet.
Code is below. I'd like to find out how to make this function work, or pointed to another function that will serve the same purpose.
Public Shared Function GetValue(Optional ByVal SQL As String = "", Optional ByVal FieldName As String = "", Optional ByVal TableName As String = "", Optional ByVal WhereClause As String = "") As VariantType?
Dim myConnection As SqlConnection
Dim myCommand As SqlCommand
Dim strSQL As New SQLStringBuilder
Dim DR As SqlDataReader
myConnection = New SqlConnection(ConfigurationManager.ConnectionStrings("ConnAFRAMSSQL").ConnectionString)
strSQL.Add(SQL)
If FieldName > "" Then
strSQL.Add("SELECT " & FieldName)
End If
If TableName > "" Then
strSQL.Add("FROM " & TableName)
End If
If WhereClause > "" Then
strSQL.Add("WHERE " & WhereClause)
End If
myConnection.Open()
myCommand = New SqlCommand(strSQL.ToString, myConnection)
DR = myCommand.ExecuteReader()
If DR.HasRows Then
DR.Read()
GetValue = DR(0)
Else
GetValue = Nothing
End If
End Function
Thanks.
You may specify the System.Object (System.Object is the ultimate base class of all types) return type of your method.
Public Shared Function GetValue(Optional ByVal SQL As String = "", Optional ByVal FieldName As String = "", Optional ByVal TableName As String = "", Optional ByVal WhereClause As String = "") As Object
Dim myConnection As SqlConnection
....
Dim obj as Object=Nothing
If DR.Read()
obj=DR(0)
End If
DR.Close()
myConnection.Close()
return obj
End Function

Resources