vb.net 调用 Web 服务函数从 Windows 窗体返回列表(字符串)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15334830/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 12:43:38  来源:igfitidea点击:

Calling Web Service Function returns List (Of String) from Windows Form

vb.netwinformsweb-serviceslistasmx

提问by Dav

I have a Web Service with multiple functions that do a job with SQL Server 2012 database. My aim is to have a Windows Service that uses this web service functions to select and insert to a database.

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

The current web service have different functions types that returns boolean, string or list of string. Everything works fine except when calling function that returns list of string getGames () from a Windows Form. (Windows Form as a replica for Windows Service)

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

Error: Value of type '1-dimensional array of Object' cannot be converted to 'System.collections.generic.list(Of String)'

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

From the Windows Form project I added a web service - Add Service Reference > Advanced > Add Web Reference. I am still a student so I don't have much experience on web services. Windows Service is created on Framework 3.5 and Windows Form on Framework 4.5 (not sure if this makes a difference) Error:

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

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

Here's the web service function

这是网络服务功能

<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

Here's how I'm calling the web service function:

这是我调用 Web 服务功能的方式:

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

Here's the query:

这是查询:

 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

采纳答案by Steven Doggart

The reason that happens is because your web service is not returning an actual .NET Listobject, it's simply returning an XML representation of the list using the standard SOAP format for lists. As such, the type used to return the data on the client-side is completely determined by the code on the client.

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

When you add a reference to a web service, Visual Studio automatically generates proxy classes for you. The proxy classes are client-side replicas of the web methods defined on the server-side. However, for lists, the client-side has no way of knowing what specific .NET type of list was returned by the web method. As far as it knows, the web service may not have even been written in a .NET language as all. Therefore, it has to arbitrarily pick a way to represent the data in the proxy class. The default list type that is used in proxy classes is simple arrays.

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

When you are added the reference to the web service, if you add it as a Web Reference, you are not given an option to specify the type to use for lists. Web Referencesalways use arrays for lists. If, however, you are adding the reference as Service Reference, then you can change the type that will be used in the proxy classes to represent lists. To do so, when adding the reference, click the Advancedbutton. Then, in the Data Typesection change the Collection typefrom System.Arrayto System.Collections.Generic.List.

当您添加对 Web 服务的引用时,如果您将其添加为Web 引用,您将无法指定用于列表的类型。 Web References总是使用数组作为列表。但是,如果您将引用添加为Service Reference,那么您可以更改将在代理类中用于表示列表的类型。为此,在添加引用时,单击高级按钮。然后,在数据类型部分将集合类型从更改System.ArraySystem.Collections.Generic.List

If you are stuck leaving your proxy classes using arrays, you can still make it work by simply converting the array to a List, like this:

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

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