Iterate through JSON array in webmethod using vb.net - asp.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)

Related

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

Handle DBNull in an object initializer

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")

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)

TVP - Failed to convert parameter value from a SqlParameter to a IEnumerable`1

I am trying to create a general purpose function which can accept tvp.
I am getting error 'Failed to convert parameter value from a SqlParameter to a IEnumerable`1.'
Dim param As New SqlParameter("#parName", GetTVP(lstDates))
param.SqlDbType = SqlDbType.Structured
sqlProvider.ExecuteNonQueryV2("sp_Save", CommandType.StoredProcedure, param)
---------------------
Public Function ExecuteNonQuery(ByVal spname As String, ByRef returnValue As Integer, ByVal ParamArray parameterValues() As Object) As Integer
Dim connection As SqlConnection = Nothing
Dim transaction As SqlTransaction = Nothing
Dim command As SqlCommand = Nothing
Dim r As Integer = -1
Try
connection = New SqlConnection(myconnectionString)
command = New SqlCommand(spname, connection)
command.CommandType = CommandType.StoredProcedure
connection.Open()
SqlCommandBuilder.DeriveParameters(command)
Me.SetParameters(command, parameterValues)
transaction = connection.BeginTransaction()
command.Transaction = transaction
r = command.ExecuteNonQuery()
transaction.Commit()
Catch ex As Exception
Finally
End Try
Return r
End Function
---------------------
Private Sub SetParameters(ByVal cmd As SqlCommand, ByVal parameterValues() As Object)
Dim i As Integer
For Each param As SqlParameter In cmd.Parameters
param.Value = parameterValues(i)
i += 1
Next
End Sub
ADDED
I have updated the code and take the "SqlCommandBuilder.DeriveParameters(command)" out and now passing parameter as a sqlparameter list. All works fine now :)
But i like to know why is it working when i have not defined the parameter type to SqlDbType.Structured ? Isn't it required?
Dim par As New List(Of SqlParameter)
par.Add(New SqlParameter("#parName", GetTVP(lstDates))
---------------
connection = New SqlConnection(myconnectionString)
command = New SqlCommand(spname, connection)
command.CommandType = CommandType.StoredProcedure
connection.Open()
Me.SetParameters(command, parameterValues)
transaction = connection.BeginTransaction()
command.Transaction = transaction
r = command.ExecuteNonQuery()
transaction.Commit()
Why don't you pass in the signature a list of SqlParameter instead of a list of objects as parameters?
You can do it this way;
Public Function ExecuteNonQuery(ByVal spname As String,
ByRef returnValue As Integer,
ByRef parameters As List(Of SqlParameter)) As Integer
Then you can loop and add
For Each para As SqlParameter In parameters
command.Parameters.Add(para)
Next
Check this link out http://geekswithblogs.net/Rhames/archive/2008/10/29/why-you-should-always-specify-the-sqldbtype-for-an-ado.net.aspx. Ideally and recommended that you define the parameter type, however it is not mandatory.

Ado.net ExecuteReader giving duplication while binding with datagrid

I am using below mentioned Ado.net function and resultset bind with grid view, however I am getting the duplicate rows in the resultset.
Please help me out.
Thanks
Private _products As New List(Of Product)
Public Property Products As List(Of BusinessObjects.Product)
Get
Return _products
End Get
Set(ByVal value As List(Of BusinessObjects.Product))
_products = value
End Set
End Property
Public Function GetProductDetails() As List(Of Product)
Dim product As New BusinessObjects.Product
Using connection As New SqlConnection
connection.ConnectionString = ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString
connection.Open()
Using Command As New SqlCommand("select * from T_product", connection)
Dim rdr As SqlDataReader
rdr = Command.ExecuteReader
While rdr.Read()
product.ProductID = rdr("ProductID")
product.ProductName = rdr("ProductName")
Products.Add(product)
End While
GridView1.DataSource = Products
GridView1.DataBind()
End Using
End Using
Return Products
End Function
You should make Dim product As New BusinessObjects.Product initialization inside while reading from SqlDataReader instance
Set(ByVal value As List(Of BusinessObjects.Product))
_products = value
End Set
End Property
Public Function GetProductDetails() As List(Of Product)
Using connection As New SqlConnection
connection.ConnectionString = ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString
connection.Open()
Using Command As New SqlCommand("select * from T_product", connection)
Dim rdr As SqlDataReader
rdr = Command.ExecuteReader
While rdr.Read()
Dim product As New BusinessObjects.Product
product.ProductID = rdr("ProductID")
product.ProductName = rdr("ProductName")
Products.Add(product)
End While
GridView1.DataSource = Products
GridView1.DataBind()
End Using
End Using
Return Products
End Function
The problem is you are updating and adding same product every time. Create product object inside the While loop as below.
Public Function GetProductDetails() As List(Of Product)
Using connection As New SqlConnection
connection.ConnectionString = ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString
connection.Open()
Using Command As New SqlCommand("select * from T_product", connection)
Dim rdr As SqlDataReader
rdr = Command.ExecuteReader
While rdr.Read()
Dim product As New BusinessObjects.Product ' product object create here
product.ProductID = rdr("ProductID")
product.ProductName = rdr("ProductName")
Products.Add(product)
End While
GridView1.DataSource = Products
GridView1.DataBind()
End Using
End Using
Return Prod

Resources