Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SAP Sybase SQL Anywhere 16.0 (中文) » SQL Anywhere 服务器 - 编程 » HTTP Web 服务 » HTTP Web 服务示例 » 教程:使用 Visual C# 访问 SOAP/DISH Web 服务

 

第 2 课:创建与 Web 服务器通信的 Visual C# 应用程序

在本课中,您将创建与 Web 服务器通信的 Visual C# 应用程序。

前提条件

本课假设您已经按照第 1 课中说明的方式设置了 Web 服务器。请参见第 1 课:设置用于接收 SOAP 请求和发送 SOAP 响应的 Web 服务器

完成本课需要最新版本的 Visual Studio。

本课假定您拥有在教程教程:使用 Visual C# 访问 SOAP/DISH Web 服务开头的特权部分中列出的角色和特权。

上下文和注释

本课中包含对 localhost 的引用。如果 Web 客户端与 Web 服务器运行在不同的计算机上,则使用第 1 课中 Web 服务器的主机名或 IP 地址而不是 localhost

本示例使用 .NET Framework 2.0 中的函数。

 任务
  1. 启动 Visual Studio。

  2. 新建一个 Visual C# Windows 窗体应用程序项目。

    将出现一个空的窗体。

  3. 向项目添加 Web 引用。

    1. 单击 [Project] » [Add Service Reference]。

    2. 在 [Add Service Reference] 窗口中,单击 [Advanced]。

    3. 在 [Service Reference Settings] 窗口中,单击 [Add Web Reference]。

    4. 在 [Add Web Reference] 窗口中的 URL 字段中,键入 http://localhost:8082/demo/SASoapTest_DNET

    5. 单击 [Go](或绿色箭头)。

      Visual Studio 列出了 SASoapTest_DNET 服务里可用的 EmployeeList 方法。

    6. 单击 [Add Reference]。

      Visual Studio 将 localhost 添加到 [Solution Explorer] 窗格的项目 [Web References] 中。

  4. 用 Web 客户端应用程序所需的对象填充空窗体。

    将 ListBox 和 Button 对象从 [Toolbox] 窗格中拖到窗体上,并更新文本属性,使窗体与下图类似:

    SOAP 演示窗体。
  5. 编写访问 Web 参考并使用可用方法的过程。

    双击 [Employee List] 按钮,然后为按钮的 click 事件添加以下代码:



    int sqlCode;
    
    listBox1.Items.Clear();
    
    localhost.SASoapTest_DNET proxy = new localhost.SASoapTest_DNET();
    DataSet results = proxy.EmployeeList(out sqlCode);
    DataTableReader dr = results.CreateDataReader();
    
    listBox1.BeginUpdate();
    while (dr.Read())
    {
        for (int i = 0; i < dr.FieldCount; i++)
        {
            string dataTypeName = dr.GetDataTypeName(i);
            string dataName = dr.GetName(i);
            System.Type ftype = dr.GetFieldType(i);
            System.TypeCode typeCode = System.Type.GetTypeCode(ftype);
    
            string columnName = "(" + dataTypeName + ")" + dataName + "=";
    
            if (dr.IsDBNull(i))
            {
                listBox1.Items.Add(columnName + "(null)");
            }
            else
            {
                switch (typeCode)
                {
                    case System.TypeCode.Int32:
                        Int32 intValue = dr.GetInt32(i);
                        listBox1.Items.Add(columnName + intValue);
                        break;
                    case System.TypeCode.Decimal:
                        Decimal decValue = dr.GetDecimal(i);
                        listBox1.Items.Add(columnName + decValue.ToString("c"));
                        break;
                    case System.TypeCode.String:
                        string stringValue = dr.GetString(i);
                        listBox1.Items.Add(columnName + stringValue);
                        break;
                    case System.TypeCode.DateTime:
                        DateTime dateValue = dr.GetDateTime(i);
                        listBox1.Items.Add(columnName + dateValue);
                        break;
                    case System.TypeCode.Boolean:
                        Boolean boolValue = dr.GetBoolean(i);
                        listBox1.Items.Add(columnName + boolValue);
                        break;
                    default:
                        listBox1.Items.Add(columnName + "(unsupported)");
                        break;
                }
            }
        }
        listBox1.Items.Add("");
    }
    listBox1.EndUpdate();
    dr.Close();
  6. 运行应用程序。

    单击 [Debug] » [Start Debugging]。

  7. 与 Web 数据库服务器通信。

    单击 [Employee List]。

    ListBox 对象以 (type)name=value 对形式显示 EmployeeList 结果集。以下输出说明了条目如何在 ListBox 对象上显示:



    (Int32)EmployeeID=102
    (Int32)ManagerID=501
    (String)Surname=Whitney
    (String)GivenName=Fran
    (Int32)DepartmentID=100
    (String)Street=9 East Washington Street
    (String)City=Cornwall
    (String)State=NY
    (String)Country=USA
    (String)PostalCode=02192
    (String)Phone=6175553985
    (String)Status=A
    (String)SocialSecurityNumber=017349033
    (Decimal)Salary=$45,700.00
    (DateTime)StartDate=8/28/1984 12:00:00 AM
    (DateTime)TerminationDate=(null)
    (DateTime)BirthDate=6/5/1958 12:00:00 AM
    (Boolean)BenefitHealthInsurance=True
    (Boolean)BenefitLifeInsurance=True
    (Boolean)BenefitDayCare=False
    (String)Sex=F

    Salary 金额已被转换为客户端的货币形式。

    对于只包含日期而不包含时间的值,将指派 00:00:00 或午夜作为时间(其显示格式取决于客户端的区域设置)。

    使用 DataTableReader.IsDBNull 方法对包含空值的值进行测试。

结果

来自 Web 服务器的 XML 响应包括已设置格式的结果集。所有列数据都转换为数据的字符串表示形式。以下结果集说明了结果集在发送给客户端时的格式:



<row>
 <EmployeeID>102</EmployeeID>
 <ManagerID>501</ManagerID>
 <Surname>Whitney</Surname>
 <GivenName>Fran</GivenName>
 <DepartmentID>100</DepartmentID>
 <Street>9 East Washington Street</Street>
 <City>Cornwall</City>
 <State>NY</State>
 <Country>USA</Country>
 <PostalCode>02192</PostalCode>
 <Phone>6175553985</Phone>
 <Status>A</Status>
 <SocialSecurityNumber>017349033</SocialSecurityNumber>
 <Salary>45700.000</Salary>
 <StartDate>1984-08-28</StartDate>
 <BirthDate>1958-06-05</BirthDate>
 <BenefitHealthInsurance>1</BenefitHealthInsurance>
 <BenefitLifeInsurance>1</BenefitLifeInsurance>
 <BenefitDayCare>0</BenefitDayCare>
 <Sex>F</Sex>
 </row>

上一课中指定了 DATATYPE ON 子句以生成 XML 结果集响应中的数据类型信息。来自 Web 服务器的响应片段如下所示。该类型信息与数据库列的数据类型相匹配。



<xsd:element name='EmployeeID' minOccurs='0' type='xsd:int' />
<xsd:element name='ManagerID' minOccurs='0' type='xsd:int' />
<xsd:element name='Surname' minOccurs='0' type='xsd:string' />
<xsd:element name='GivenName' minOccurs='0' type='xsd:string' />
<xsd:element name='DepartmentID' minOccurs='0' type='xsd:int' />
<xsd:element name='Street' minOccurs='0' type='xsd:string' />
<xsd:element name='City' minOccurs='0' type='xsd:string' />
<xsd:element name='State' minOccurs='0' type='xsd:string' />
<xsd:element name='Country' minOccurs='0' type='xsd:string' />
<xsd:element name='PostalCode' minOccurs='0' type='xsd:string' />
<xsd:element name='Phone' minOccurs='0' type='xsd:string' />
<xsd:element name='Status' minOccurs='0' type='xsd:string' />
<xsd:element name='SocialSecurityNumber' minOccurs='0' type='xsd:string' />
<xsd:element name='Salary' minOccurs='0' type='xsd:decimal' />
<xsd:element name='StartDate' minOccurs='0' type='xsd:date' />
<xsd:element name='TerminationDate' minOccurs='0' type='xsd:date' />
<xsd:element name='BirthDate' minOccurs='0' type='xsd:date' />
<xsd:element name='BenefitHealthInsurance' minOccurs='0' type='xsd:boolean' />
<xsd:element name='BenefitLifeInsurance' minOccurs='0' type='xsd:boolean' />
<xsd:element name='BenefitDayCare' minOccurs='0' type='xsd:boolean' />
<xsd:element name='Sex' minOccurs='0' type='xsd:string' />

在 XML 响应中,只含有日期的列的格式为 yyyy-mm-dd

在 XML 响应中,只含有时间的列的格式为 hh:mm:ss.nnn-HH:MMhh:mm:ss.nnn+HH:MM。将向字符串后添加时区偏移(-HH:MM 或 +HH:MM)后缀。

在 XML 响应中,同时含有日期和时间的列的格式为 yyyy-mm-ddThh:mm:ss.nnn-HH:MMyyyy-mm-ddThh:mm:ss.nnn+HH:MM。使用字母 'T' 分隔日期和时间。将向字符串后添加时区偏移(-HH:MM 或 +HH:MM)后缀。

在 XML 响应中,含有日期、时间和时区偏移的列的格式为 yyyy-mm-ddThh:mm:ss.nnn-HH:MMyyyy-mm-ddThh:mm:ss.nnn+HH:MM。使用字母 'T' 分隔日期和时间。将向字符串后添加时区偏移(-HH:MM 或 +HH:MM)后缀。

一些以太平洋时区运行的服务器示例如下所示:

<ADate>2013-01-27</ADate>
<ATime>12:34:56.000-08:00</ATime>
<ADateTime>2013-01-27T12:34:56.000-08:00</ADateTime>
<ADateTimeWithZone>2013-01-27T12:34:56.000+06:00</ADateTimeWithZone>

这些日期和时间在 .NET 应用程序中的显示格式取决于客户端的时区和区域设置。以下是一个使用美国区域设置的东部时区客户端示例(假设今天的日期是 2013 年 1 月 28 日)。

(DateTime)ADate=1/27/2013 12:00:00 AM 
(DateTime)ATime=1/28/2013 3:34:56 PM
(DateTime)ADateTime=1/27/2013 3:34:56 PM
(DateTime)ADateTimeWithZone=1/27/2013 1:34:56 AM

请注意,TypeCode 枚举中没有单独的 Date 和 Time - 只有 TypeCode.DateTime - 这解释了为什么所有的结果均同时包括日期和时间。

这些日期和时间的 XML 响应中的数据类型信息如下所示:

<xsd:element name='ADate' minOccurs='0' type='xsd:date' />
<xsd:element name='ATime' minOccurs='0' type='xsd:time' />
<xsd:element name='ADateTime' minOccurs='0' type='xsd:dateTime' />
<xsd:element name='ADateTimeWithZone' minOccurs='0' type='xsd:dateTime' />