Needing to get a list of strings into a webservice - asp.net

I am creating a web service via asp.net. I want to pull as a list the Address's of the Fuel Stops as shown below unfortunately what I am getting is the string name of address's as shown below from the xml...
Unfortunately when I do run this I get a xml file filled with
-<FuelStop>
<Physical_Address_Street>Physical_Address_Street</Physical_Address_Street>
<Physical_Address_Local>Physical_Address_Local</Physical_Address_Local>
<Physical_Address_State>Physical_Address_State</Physical_Address_State>
<Physical_Address_Zip>Physical_Address_Zip</Physical_Address_Zip>
<Phone_Number>Phone_Number</Phone_Number>
</FuelStop>
Versus getting the address info that is populated in the database.
Below is my code.
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.ComponentModel
Imports System.Data
Imports System.Data.SqlClient
<System.Web.Services.WebService(Namespace:="http://watersports.com 8010/", Description:="Holds Fuel Stop and Shelter information", Name:="ShelterandFuelService")> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<ToolboxItem(False)> _
Public Class Service1
Inherits System.Web.Services.WebService
<WebMethod()> _
Public Function GetAddresses(ByVal skip As Integer, ByVal take As Integer) As FuelStop()
Dim sqlCon As New SqlConnection
Dim resultList = New List(Of FuelStop)()
Try
sqlCon.ConnectionString = "Data Source=google.watersports.com;Initial Catalog=myDb;Persist Security Info=True;Connect Timeout=30;User ID=****;Password=******"
Dim command As New SqlCommand("SELECT #Physical_Address_Street, #Physical_Address_Local, #Physical_Address_State, #Physical_Address_Zip, #Phone_Number FROM Gas_Stations WHERE Location_Type = 1")
command.Parameters.Add("#Physical_Address_Street", SqlDbType.VarChar, 50).Value = "Physical_Address_Street"
command.Parameters.Add("#Physical_Address_Local", SqlDbType.VarChar, 50).Value = "Physical_Address_Local"
command.Parameters.Add("#Physical_Address_State", SqlDbType.VarChar, 50).Value = "Physical_Address_State"
command.Parameters.Add("#Physical_Address_Zip", SqlDbType.VarChar, 50).Value = "Physical_Address_Zip"
command.Parameters.Add("#Phone_Number", SqlDbType.VarChar, 50).Value = "Phone_Number"
command.Connection = sqlCon
sqlCon.Open()
'command.ExecuteNonQuery()
Using reader = command.ExecuteReader()
While reader.Read()
Dim fuelStop = New FuelStop()
fuelStop.Physical_Address_Street = reader.GetString(0)
fuelStop.Physical_Address_Local = reader.GetString(1)
fuelStop.Physical_Address_State = reader.GetString(2)
fuelStop.Physical_Address_Zip = reader.GetString(3)
fuelStop.Phone_Number = reader.GetString(4)
resultList.Add(fuelStop)
End While
End Using
Catch ex As Exception
sqlCon.Close()
Finally
sqlCon.Close()
End Try
Return resultList.Skip(skip).Take(take).ToArray()
Based on the Sql Command below I will return possibly a few hundred address's how do I incorporparate this into my vb.net logic to return the list of address's?
Dim command As New SqlCommand("SELECT Physical_Address_Street, Physical_Address_Local, Physical_Address_State, Physical_Address_Zip, Phone_Number FROM Gas_Stations WHERE Location_Type = 1")
And here is my Fuel stop class
Public Class FuelStop
Property Physical_Address_Street As String
Property Physical_Address_Local As String
Property Physical_Address_State As String
Property Physical_Address_Zip As String
Property Phone_Number As String
End Class

The below code should give you what you are looking for. I am not sure if WebMethods can return custom objects like the Address object below. If it can not do that then you could convert the return type to String() and turn each Address object into a json object.
If I was doing this from scratch, I would just return a single JSON array that contained a list of Address objects.
Also, I have included in this method signature a skip and take parameter, as you mentioned in your comment, the web service sql query is unbounded so it could return hundreds of addresses. By using the skip and take you can limit how many are returned at once and can page through them from the client. To reduce the size of the sql query you could pass the skip and take parameters into the sql query to reduce the number of rows returned, which would improve performance as the number of addresses grows.
There are additional safety checks you can include in the below code to prevent errors but this can get you moving.
<WebMethod> _
Public Function GetAddresses(skip As Integer, take As Integer) As Address()
Dim resultList = New List(Of Address)()
Using sqlCon As New SqlConnection()
sqlCon.ConnectionString = "Data Source=google.watersports.com;Initial Catalog=myDb;Persist Security Info=True;Connect Timeout=30;User ID=****;Password=******"
Dim command As New SqlCommand("SELECT Physical_Address_Street, Physical_Address_Local, Physical_Address_State, Physical_Address_Zip, Phone_Number FROM Gas_Stations WHERE Location_Type = 1")
sqlCon.Open()
Using reader = command.ExecuteReader()
While reader.Read()
Dim addr = New Address()
addr.Physical_Address_Street = reader.GetString(0)
addr.Physical_Address_Local = reader.GetString(1)
addr.Physical_Address_State = reader.GetString(2)
addr.Physical_Address_Zip = reader.GetString(3)
addr.Phone_Number = reader.GetString(4)
resultList.Add(addr)
End While
End Using
End Using
Return resultList.Skip(skip).Take(take).ToArray()
End Function
Below is a temp class object that is used above.
public class Address
{
public string Physical_Address_Street { get; set; }
public string Physical_Address_Local { get; set; }
public string Physical_Address_State { get; set; }
public string Physical_Address_Zip { get; set; }
public string Phone_Number { get; set; }
}

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)

populating a formview

If I have a class called "car" and this car class uses a SQL query to fill properties like ID, Name, Type, Model, Engine, and Size. How can I populate an asp:formview with that data?
I tried this:
Private currentCar As car
fvCarview.DataSource = currentCar
fvCarview.DataBind()
but I keep on getting this error:
Data source is an invalid type. It must be either an IListSource, IEnumerable, or IDataSource.
Any help would be appreciated!
Thanks
An easy way would be to use a List(Of Car) with a single car in it or a single IEnumerable(Car) via carList.Where(Function(c) c.ID = carID). You could also use a SqlDataAdapter to fill a DataTable and table.Where(Function(r) r.Field(Of Int32)("ID") = carID). Or just select the single car from database which is also the most efficiant way when you don't need the complete list anyway:
DataTable:
Private Sub fillFormView(carID As Int32)
Using con = New SqlConnection(My.Settings.SqlConnection)
Using da = New SqlDataAdapter("SELECT ID, Name, Type, Model, Engine, Size FROM TCAR WHERE ID=#ID", con)
da.SelectCommand.Parameters.AddWithValue("#ID", carID)
Dim table = New DataTable
da.Fill(table)
fvCarview.DataSource = table
fvCarview.DataBind()
End Using
End Using
End Sub
Here's your custom Car-Class approach with a single car in a List(Of Car):
Class Car
Public Property ID As Int32
Public Property Name As String
Public Property Type As String
Public Property Model As String
Public Property Engine As String
Public Property Size As Double
End Class
Private Sub fillFormView(carID As Int32)
Using con = New SqlConnection(My.Settings.SqlConnection)
Using cmd = New SqlCommand("SELECT ID, Name, Type, Model, Engine, Size FROM TCAR WHERE ID=#ID", con)
cmd.Parameters.AddWithValue("#ID", carID)
con.Open()
Using rd = cmd.ExecuteReader()
rd.Read()
Dim carList = New List(Of Car)
Dim car = New Car()
car.ID = rd.GetInt32(0)
car.Name = rd.GetString(1)
car.Type = rd.GetString(2)
car.Model = rd.GetString(3)
car.Engine = rd.GetString(4)
car.Size = rd.GetDouble(5)
carList.Add(car)
fvCarview.DataSource = carList
fvCarview.DataBind()
End Using
End Using
End Using
End Sub

Information retreival from sql server database

I want to retreive customer information from microsoft sql server database using just his/her user id onto a web form, can i get some help with this.
You could start by writing a class which will define what a customer is:
Public Class Customer
Public Property Id As Integer
Public Property FirstName As String
Public Property LastName As String
End Class
Then a method to retrieve this customer from the database:
Public Function GetCustomer(ByVal CustomerId As Integer) As Customer
Using conn = New SqlConnection("Data Source=serverName;Initial Catalog=databaseName;User Id=username;Password=password;")
Using cmd = conn.CreateCommand()
conn.Open()
cmd.CommandText = "SELECT id, first_name, last_name FROM customers WHERE id = #id"
cmd.Parameters.AddWithValue("#id", CustomerId)
Using reader = cmd.ExecuteReader()
While reader.Read()
Dim Customer = New Customer()
Customer.Id = reader.GetInt32(reader.GetOrdinal("id"))
Customer.FirstName = reader.GetInt32(reader.GetOrdinal("first_name"))
Customer.LastName = reader.GetInt32(reader.GetOrdinal("last_name"))
Return Customer
End While
End Using
End Using
End Using
Return Nothing
End Function
and finally call this function in your web form:
Dim Customer = GetCustomer(123)
FirstNameTextBox.Text = Customer.FirstName
...
And if you want to avoid writing SQL queries in your code you could use an ORM such as the Entity Framework.

Resources