调用Web服务函数从Windows窗体返回List(Of String)

时间:2013-03-11 09:17:22

标签: vb.net winforms web-services list asmx

我有一个具有多个功能的Web服务,可以使用SQL Server 2012数据库。我的目标是让Windows服务使用此Web服务功能来选择和插入数据库。

当前的Web服务具有不同的函数类型,它们返回布尔值,字符串或字符串列表。一切正常,除非调用从Windows窗体返回字符串getGames()列表的函数。 (Windows窗体作为Windows服务的副本)

错误:'对象的一维数组'类型的值无法转换为'System.collections.generic.list(Of String)'

在Windows窗体项目中,我添加了一项Web服务 - 添加服务参考>高级>添加Web引用。我还是学生,所以我没有太多的网络服务经验。 Windows服务是在Framework 3.5和Windows窗体上的Windows窗体上创建的(不确定这是否有所不同) 错误:

listOfGames = ws.getGames("username123", "password123") '** Error Here

这是网络服务功能

<WebMethod()> _
Public Function getGames(ByVal username As String, ByVal password As String) As List(Of String)
    Dim m As DBMember = DBMember.verifyUsername(username, password)
    If m IsNot Nothing Then
        Dim gList As New List(Of String)
        gList = DBGame.selectAllGames()
        Return gList
    End If
    Return Nothing
End Function

以下是我如何调用Web服务功能:

    Private Sub onStart()
    Dim ws As localhost.Service1 = New localhost.Service1
    listOfGames = ws.getGames("username123", "password123") '** Error Here
End Sub

以下是查询:

 Shared Function selectAllGames() As List(Of String)
    Dim cmd As New SqlCommand
    cmd.CommandText = "SELECT g_Exe FROM Game"
    cmd.Connection = DB.Conn()

    Dim rdr As SqlDataReader = cmd.ExecuteReader()
    Dim gList As New List(Of String)

    If rdr.HasRows Then
        While rdr.Read
            gList.Add(rdr.Item("g_Exe").ToString())
        End While
    End If

    DB.CloseDB()
    Return gList
End Function

1 个答案:

答案 0 :(得分:3)

发生这种情况的原因是因为您的Web服务没有返回实际的.NET List对象,它只是使用列表的标准SOAP格式返回列表的XML表示形式。因此,用于在客户端返回数据的类型完全由客户端上的代码确定。

当您添加对Web服务的引用时,Visual Studio会自动为您生成代理类。代理类是服务器端定义的Web方法的客户端副本。但是,对于列表,客户端无法知道Web方法返回的特定.NET类型的列表。据他所知,Web服务甚至可能都不是用.NET语言编写的。因此,它必须随意选择一种表示代理类中数据的方法。代理类中使用的默认列表类型是简单数组。

当您添加对Web服务的引用时,如果将其添加为 Web引用,则不会为您指定用于列表的类型。 Web引用始终使用列表列表。但是,如果要将引用添加为服务引用,则可以更改将在代理类中使用的类型来表示列表。为此,在添加引用时,单击高级按钮。然后,在数据类型部分中,将集合类型System.Array更改为System.Collections.Generic.List

如果您因使用数组而遗忘您的代理类,您仍然可以通过简单地将数组转换为List来实现它,如下所示:

Dim listOfGames As New List(Of String)()
listOfGames.AddRange(ws.getGames("username123", "password123"))