3

我有一个具有多种功能的 Web 服务,这些功能与 SQL Server 2012 数据库一起工作。我的目标是拥有一个使用此 Web 服务功能来选择和插入数据库的 Windows 服务。

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

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

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

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
4

1 回答 1

3

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

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

当您添加对 Web 服务的引用时,如果您将其添加为Web 引用,则不会为您提供指定用于列表的类型的选项。 Web References总是使用数组作为列表。但是,如果您将引用添加为Service Reference,那么您可以更改将在代理类中用于表示列表的类型。为此,在添加参考时,单击高级按钮。然后,在Data Type部分将Collection 类型从更改System.ArraySystem.Collections.Generic.List

如果您坚持使用数组离开代理类,您仍然可以通过简单地将数组转换为 a 来使其工作List,如下所示:

Dim listOfGames As New List(Of String)()
listOfGames.AddRange(ws.getGames("username123", "password123"))
于 2013-03-11T13:22:32.193 回答