Passing custom objects in web services

R

Roshawn

Hi,

I have created a web service that connects to the Northwind database on SQL
Server 2K. It contains three methods: GetCategories,
GetProductsByCategory, and GetProductsByCategoryFromArray. The first two
methods return DataSet objects and are bound to a dropdownlist and DataGrid
controls. I have no problems with either of the two methods.

However, the third method gives me trouble on the client side. It is bound
to another DataGrid control. Each time that I try to call the method I get
an error:

DataGrid with id 'DataGrid2' could not automatically generate any columns
from the selected data source.

Could anyone help me with this problem? I have included my code for your
review. Any help would be appreciated.

Thanks in advance,
Shawn

Web Service code below
Imports System.Web.Services

Imports System.Data

Imports System.Data.SqlClient

Imports System.Configuration

<WebService(Namespace := "http://tempuri.org/")> _

Public Class Northwind

Inherits System.Web.Services.WebService

Dim da As SqlDataAdapter

Dim ds As DataSet

<Serializable()> _

Public Structure Product

Dim ProductID As String

Dim CategoryID As String

Dim ProductName As String

Dim UnitPrice As String

End Structure

<WebMethod(Description:="Returns all categories from the Products table.")>
_

Public Function GetCategories() As DataSet

Dim ocon As New SqlConnection(ConfigurationSettings.AppSettings("constr"))

da = New SqlDataAdapter("GetCategories", ocon)

da.SelectCommand.CommandType = CommandType.StoredProcedure

ds = New DataSet()

da.Fill(ds, "Categories")

Return ds

End Function

<WebMethod(Description:="Returns all products in the given categoryID.")> _

Public Function GetProductsByCategory(ByVal categoryID As Integer) As
DataSet

Dim ocon As New SqlConnection(ConfigurationSettings.AppSettings("constr"))

da = New SqlDataAdapter("GetProducts", ocon)

da.SelectCommand.CommandType = CommandType.StoredProcedure

ds = New DataSet()

da.Fill(ds, "Products")

Dim dt As DataTable = ds.Tables("Products").Clone()

Dim dv As DataView = New DataView(ds.Tables("Products"))

dv.RowFilter = "CategoryID = '" & categoryID & "'"

Dim drv As DataRowView

For Each drv In dv

dt.ImportRow(drv.Row)

Next

Dim newds As New DataSet()

newds.Tables.Add(dt)

Return newds

End Function

<WebMethod(Description:="Returns all products in the given categoryID via an
array.")> _

Public Function GetProductsByCategoryFromArray(ByVal categoryID As Integer)
As Product()

ds = GetProductsByCategory(categoryID)

Dim _rows As DataRowCollection = ds.Tables("Products").Rows

'Allocate the array

Dim Products(_rows.Count) As Product

Dim i As Integer = 0

Dim _row As DataRow

For Each _row In _rows

Dim p As Product = New Product()

With p

..ProductID = _row("ProductID").ToString()

..CategoryID = _row("CategoryID").ToString()

..ProductName = _row("ProductName").ToString()

..UnitPrice = _row("UnitPrice").ToString()

End With

Products(i) = p

i += 1

Next

Return Products

End Function



Client code below

Public Class WebForm1

Inherits System.Web.UI.Page

Protected WithEvents DropDownList1 As System.Web.UI.WebControls.DropDownList

Protected WithEvents DataGrid1 As System.Web.UI.WebControls.DataGrid

Protected WithEvents Button1 As System.Web.UI.WebControls.Button

Protected WithEvents Button2 As System.Web.UI.WebControls.Button

Protected WithEvents DataGrid2 As System.Web.UI.WebControls.DataGrid

Dim wbs As New localhost.Northwind()

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

If Not Page.IsPostBack Then

Me.DropDownList1.DataSource = wbs.GetCategories()

Me.DropDownList1.DataTextField = "CategoryName"

Me.DropDownList1.DataValueField = "CategoryID"

Me.DropDownList1.DataBind()

End If

End Sub

Private Sub Button1_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Button1.Click

Me.DataGrid1.DataSource =
wbs.GetProductsByCategory(Me.DropDownList1.SelectedItem.Value)

Me.DataGrid1.DataBind()

End Sub

Private Sub Button2_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Button2.Click

Me.DataGrid2.DataSource =
wbs.GetProductsByCategoryFromArray(Me.DropDownList1.SelectedItem.Value)

Me.DataGrid2.DataBind()

End Sub

End Class
 
D

Dino Chiesa [Microsoft]

Impedance mismatch.

If you look at the Product type on the client side - this is a type that is
generated by the wsdl.exe compiler, or the step in VS.NET when you click Add
Web Reference... - this type will include public FIELDS. On the other hand,
the doc for the datagrid says it will bind to public PROPERTIES, which is
not the same.

To fixup this mismatch, you can modify the generated type to convert each
public FIELD to a PROPERTY.
If you want a more general solution, you can use System.CodeDom to generate
a wrapper type that exposes the fields as properties automatically.

Here's a brief description of the problem, as well as source code for the
proposed general solution.

http://www.winisp.net/cheeso/examples.aspx#Misc
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top