WebService引用以及说明

1.  什么是webservice
从表面上看,Web service 就是一个应用程序,它向外界暴露出一个能够通过Web进行调用的API。这就是说,你能够用编程的方法通过Web来调用这个应用程序。
对Web service 更精确的解释: Web services是建立可互操作的分布式应用程序的新平台。作为一个Windows程序员,你可能已经用COM或DCOM建立过基于组件的分布式应用程序。COM是一个非常好的组件技术,但是我们也很容易举出COM并不能满足要求的情况。Web service平台是一套标准,它定义了应用程序如何在Web上实现互操作性。你可以用任何你喜欢的语言,在任何你喜欢的平台上写Web service ,只要我们可以通过Web service标准对这些服务进行查询和访问。
不管你的Web service是用什么工具,什么语言写出来的,只要你用SOAP协议通过HTTP来调用它,总体结构都应如下图所示。通常,你用你自己喜欢的语言(如VB 6或者VB.NET)来构建你的Web service,然后用SOAP Toolkit或者.NET的内建支持来把它暴露给Web客户。于是,任何语言,任何平台上的客户都可以阅读其WSDL文档,以调用这个Web service。客户根据WSDL描述文档,会生成一个SOAP请求消息。Web service都是放在Web服务器 (如IIS) 后面的,客户生成的SOAP请求会被嵌入在一个HTTP POST请求中,发送到Web服务器来。Web服务器再把这些请求转发给Web service请求处理器。对VB 6程序来说,Web service请求处理器是一个与SOAP Toolkit组件协同工作的ASP页面或ISAPI extension。而对VB.NET程序来说,Web ser
vice请求处理器则是一个.NET Framework自带的ISAPI extension。请求处理器的作用在于,解析收到的SOAP请求,调用Web service,然后再生成相应的SOAP应答。Web服务器得到SOAP应答后,会再通过HTTP应答的方式把它送回到客户端。

2.  基本概念
SOAP 
Web service建好以后,其他人就会去调用它。简单对象访问协议(SOAP)提供了标准的远程过程调用( RPC)方法来调用Web service。SOAP规范定义了SOAP消息的格式,以及怎样通过HTT
P协议来使用SOAP。SOAP也是基于XML和XSD的,XML是SOAP的数据编码方式。客户端和服务端之间的方法调用请求和结果返回值都放在这些消息里。
       XML和XSD
可扩展的标记语言(XML)是Web service平台中表示数据的基本格式。除了易于建立和易于分析外,XML主要的优点在于它既是平台无关的,又是厂商无关的。无关性是比技术优越性更重要的。XML解决了数据表示的问题,但它没有定义一套标准的数据类型,更没有说怎么去扩展这套数据类型。例如,整形数到底代表什么?16位,32位,还是64位?这些细节对实现互操作性都是很重要的。W3C制定的XML Schema(XSD)就是专门解决这个问题的一套标准。它定义了一套标准的数据类型,并给出了一种语言来扩展这套数据类型。Web service平台就是用XSD来作为其数据类型系统的。当用某种语言(如VB.NET或C#)来构造一个Web service时,为了符合Web service标准,所有使用的数据类型都必须被转换为XSD类型。
       WSDL(Web Services Description Language)
用于描述服务端所提供服务的
XML格式。WSDL文件里,描述了服务端提供的服务,提供的调用方法,以及调用时所要遵循的格式,比如调用参数和返回值的格式等等。WSDL 很像COM编程里的IDL(Interface Description Language),是服务器与客户端之间的契约,双方必须按契约严格行事才能实现功能。
   WSML(Web Services Meta Language)
用于描述WSDL里提供的方法与实现该方法的COM对象之间的映射关系。该文件是Microsoft的实现中特有的,不是SOAP标准的一部分。一般情况下,该文件只在服务端存在。

3.Webservice的技术特点
长项一: 跨防火墙的通信
如果应用程序有成千上万的用户,而且分布在世界各地,那么客户端和服务器之间的通信将是一个棘手的问
题。因为客户端和服务器之间通常会有防火墙或者代理服务器。在这种情况下,使用DCOM就不是那么简单,通常也不便于把客户端程序发布到数量如此庞大的每一个用户手中。传统的做法是,选择用浏览器作为客户端,写下一大堆ASP页面,把应用程序的中间层暴露给最终用户。这样做的结果是开发难度大,程序很难维护。
举个例子,在应用程序里加入一个新页面,必须先建立好用户界面(Web页面),并在这个页面后面,包含相应商业逻辑的中间层组件,还要再建立至少一个ASP页面,用来接受用户输入的信息,调用中间层组件,把结果格式化为HTML形式,最后还要把“结果页”送回浏览器。要是客户端代码不再如此依赖于HTML表单,客户端的编程就简单多了。
如果中间层组件换成Web Service的话,就可以从用户界面直接调用中间层组件,从而省掉建立ASP页面的那一步。要调用Web Service,可以直接使用Microsoft SOAP Toolkit或.NET这样的SOA
P客户端,也可以使用自己开发的SOAP客户端,然后把它和应用程序连接起来。不仅缩短了开发周期,还减少了代码复杂度,并能够增强应用程序的可维护性。同时,应用程序也不再需要在每次调用中间层组件时,都跳转到相应的“结果页”。
从经验来看,在一个用户界面和中间层有较多交互的应用程序中,使用Web Service这种结构,可以节省花在用户界面编程上20%的开发时间。另外,这样一个由Web Service组成的中间层,完全可以在应用程序集成或其它场合下重用。最后,通过Web Service把应用程序的逻辑和数据“暴露
”出来,还可以让其它平台上的客户重用这些应用程序。
长项二: 应用程序集成
企业级的应用程序开发者都知道,企业里经常都要把用不同语言写成的、在不同平台上运行的各种程序集成起来,而这种集成将花费很大的开发力量。应用程序经常需要从运行在IBM主机上的程序中获取数据;或者把数据发送到主机或UNIX应用程序中去。即使在同一个平台上,不同软件厂商生产的各种软件也常常需要集成起来。通过Web Service,应用程序可以用标准的方法把功能和数据“暴露”出来,供其它应用程序使用。
例如,有一个订单登录程序,用于登录从客户来的新订单,包括客户信息、发货地址、数量、价格和付款方式等内容;还有一个订单执行程序,用于实际货物发送的管理。这两个程序来自不同软件厂商。一份新订单进来之后,订单登录程序需要通知订单执行程序发送货物。通过在订单执行程序上面增加一层Web Service,订单执行程序可以把“Add Order”函数“暴露”出来。这样,每当有新订单到来时,订单登录程序就可以调用这个函数来发送货物了。
长项三: B2B的集成
用Web Service集成应用程序,可以使公司内部的商务处理更加自动化。但当交易跨越供应商和客户、突破公司的界限时会怎么样呢?跨公司的商务交易集成通常叫做B2B集成。
Web Service是B2B集成成功的关键。通过Web Service,公司可以把关键的商务应用“暴露”给指定的供应商和客户。例如,把电子下单系统和电子发票系统“暴露”出来,客户就可以以电子的方式发送订单,供应商则可以以电子的方式发送原料采购发票。当然,这并不是一个新的概念, EDI(电子文档交换)早就是这样了。但是,Web Service的实现要比EDI简单得多,而且Web Service运行在Internet上,在世界任何地方都可轻易实现,其运行成本就相对较低。不过,Web Service并不像EDI那样,是文档交换或B2B集成的完整解决方案。Web Service只是B2B集成的一个关键部分,还需要许多其它的部分才能实现集成。
用Web Service来实现B2B集成的最大好处在于可以轻易实现互操作性。只要把商务逻辑“暴露”出来,成为Web Service,就可以让任何指定的合作伙伴调用这些商务逻辑,而不管他们的系统在什么平台上运行,使用什么开发语言。这样就大大减少了花在B2B集成上的时间和成本,让许多原本无法承受EDI的中小企业也能实现B2B集成。

长项四: 软件和数据重用
软件重用是一个很大的主题,重用的形式很多,重用的程度有大有小。最基本的形式是源代码模块或者类一级的重用,另一种形式是二进制形式的组件重用。

当前,像表格控件或用户界面控件这样的可重用软件组件,在市场上都占有很大的份额。但这类软件的重用有一个很大的限制,就是重用仅限于代码,数据不能重用。原因在于,发布组件甚至源代码都比较容易,但要发布数据就没那么容易,除非是不会经常变化的静态数据。
Web Service在允许重用代码的同时,可以重用代码背后的数据。使用Web Service,再也不必像以前那样,要先从第三方购买、安装软件组件,再从应用程序中调用这些组件;只需要直接调用远端的Web Service就可以了。举个例子,要在应用程序中确认用户输入的地址,只需把这个地址直接发送给相应的Web Service,这个Web Service 就会帮你查阅街道地址、城市、省区和邮政编码等信息,确认这个地址是否在相应的邮政编码区域。Web Service 的提供商可以按时间或使用次数来对这项服务进行收费。这样的服务要通过组件重用来实现是不可能的,那样的话你必须下载并安装好包含街道地址、城市、省区和邮政编码等信息的数据库,而且这个数据库还是不能实时更新的。
另一种软件重用的情况是,把好几个应用程序的功能集成起来。例如,要建立一个局域网上的门户站点应用,让用户既可以查询联邦快递包裹,查看股市行情,又可以管理自己的日程安排,还可以在线购买电影票。现在Web上有很多应用程序供应商,都在其应用中实现了这些功能。一旦他们把这些功能都通过Web Service “暴露”出来,就可以非常容易地把所有这些功能都集成到你的门户站点中,为用户提供一个统一的、友好的界面。
将来,许多应用程序都会利用Web Service,把当前基于组件的应用程序结构扩展为组件/Web Service 的混合结构,可以在应用程序中使用第三方的Web Service 提供的功能,也可以把自己的应用程序功能通过Web Service 提供给别人。两种情况下,都可以重用代码和代码背后的数据。

4.如何调用webservice
4.0 webservice的调用过程
    客户端:取得服务端的服务描述文件WSDL,解析该文件的内容,了解服务端的服务信息,以及调用方式。根据需要,生成恰当的SOAP请求消息(指定调用的方法,已经调用的参数),发往服务端。等待服务端返回的SOAP回应消息,解析得到返回值。
服务端:生成服务描述文件,以供客户端获取。接收客户端发来的SOAP请求消息,解析其中的方法调用和参数格式。根据WSDL和WSML的描述,调用相应的COM对象来完成指定功能,并把返回值放入SOAP回应消息返回给用户。
高层接口
    使用高层接口,不需要知道SOAP和XML的任何信息,就可以生成和使用一个WebService。Soap Toolkit 2.0通过提供两个COM对象――SoapClient和SoapSer
ver,来完成这些功能。
     在客户端,只需要生成一个SoapClient实例,并用WSDL作为参数来调用其中的mssoapinit方法。SoapClient对象会自动解析WSDL文件,并在内部生成所有Web Service的方法和参数信息。之后,你就可以像调用IDispatch接口里的方法一样,调用里面所有的方法。在VB或是脚本语言里,你甚至可以直接在SoapClient对象名后面直接加上.方法(参数…)进行调用。
低层接口
    要使用低层接口,你必须对SOAP和XML有所了解。你可以对SOA
P的处理过程进行控制,特别是要做特殊处理的时候。
在客户端,首先要创建一个HttpConnector对象,负责HTTP连接。设定Connector的一些头部信息,比如EndPoinURL和SoapAction等。如果网络连接需要使用代理服务器,那也要在这里设定相关的信息。接着创建SoapSerializer对象,用于生成Soap消息。按照WSDL里定义,把所有参数按顺序序列化,得到一个完整的SOAP请求消息。该Soap消息,作为Payload通过HttpConnector被发送到服务端。最后,生成一个Soa
pReader对象,负责读取服务端返回的SOAP消息,取得其中的返回值。

4.1 使用PowerBuilder调用
    适用版本8.0 需下载Bulletin Web Services Toolkit 4.1
4.2使用java调用
需要下载apache soap。下载地址:http://xml.apache.org/soap/index.html
导入:
import org.apache.soap.*;
import org.apache.soap.rpc.*;
例程:
import java.io
.*;
import java.util.*;
import java.net.*;
import org.w3c.dom.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.*;
import org.apache.soap.encoding.*;
import org.apache.soap.encoding.soapenc.*;
import org.apache.soap.rpc.*;
import org.apache.soap.transport.http.SOAPHTTPConnection;

public class testClient {

    public static void main(String[] args) throws Exception {

        URL url = new URL ("http://192.168.0.4/yundan/service1.wsdl");
//
改成你的地址
        SOAPMappingRegistry smr = new SOAPMappingRegistry ();
        StringDeserializer sd = new StringDeserializer ();
        smr.mapTypes (Constants.NS_URI_SOAP_ENC, new QName ("", "Result"), null, null, sd);

        // 创建传输路径和参数
        SOAPHTT
PConnection st = new SOAPHTTPConnection();

        // 创建调用
        Call call = new Call ();
        call.setSOAPTransport(st);
        call.setSOAPMappingRegistry (smr);

        call.setTargetObjectURI ("http://tempuri.org/message/");
        call.setMetho
dName("addNumbers");
        call.setEncodingStyleURI ("http://schemas.xmlsoap.org/soap/encoding/");

        Vector params = new Vector();
        params.addElement(new Parameter("NumberOne", Double.class, "10", null));
        params.addElement(new Parameter("NumberTwo", Double.class, "25", null));
        call.setParams(params);

        Response resp = null;

        try {
          resp = call.invoke (url, "http://tempuri.org/action/Hello2.addNumbers");
        }
        catch (SOAPException e) {
       
System.err.println("Caught SOAPException (" + e.getFaultCode () + "): " + e.getMessage ());
        return;
        }

        // 检查返回值
        if (resp != null && !resp.generatedFault()) {
        Parameter ret = resp.getReturnValue();
        Object value
= ret.getValue();

        System.out.println ("Answer--> " + value);
        }
        else {
            Fault fault = resp.getFault ();
            System.err.println ("Generated fault: ");
            System.out.println (" Fault Code = " + fault.getFaultCode());
            System.out.println (" Fault String = " + fault.getFaultString());
        }
    }
}

4. 3 在asp中使用Jscript调用
需下载msSoapToolkit20.exe
引用:MSSOAP.SoapClient
    例程:
    <%@ LANGUAGE = JScript %>
<HTML>
<HEAD>
<TITLE>webservice演示</TITLE>
</HEAD>
<BODY>
    <%
         var WSDL_URL = "http://server0/yundan/webservice1.asmx?WSDL"
           var a, b, re
s
           var soapclient
            a = 12
            b = 13   
        soapclient = Server.CreateObject("MSSOAP.SoapClient")
        soapclient.ClientProperty("ServerHTTPRequest") = true
‘在ASP中运行 需要设置ServerHTTPRequest选项
soapclient.mssoapinit("http:
//192.168.0.4/yundan/Service1.WSDL","Service1","Service1Soap","")
        res = soapclient.test(2,3)
%>
<h3>webservice 演示</h3>
<B>Result:</B> <%=res%><P><P>
</BODY>
</HTML>
4. 4在asp中使用vbscript调用
需下载msSoapToolkit20.exe
引用:MSSOAP.SoapClient
    例程:
<%@ LANG
UAGE = VBScript %>
<HTML>
<HEAD>
<TITLE>webservie演示</TITLE>
</HEAD>
<BODY>
<%
Dim soapclient
Const WSDL_URL = "http://192.168.0.4/yundan/service1.wsdl"
    set soapclient = Server.CreateObject("MSSOAP.SoapClient")
    soapclient.ClientProperty("ServerHTTPR
equest") = True
    soapclient.mssoapinit
http://192.168.0.4:8080/yundan/Service1.WSDL","Service1","Service1Soap",""
Dim res
        res = soapclient.test(23, 34)
%>
<h1>webservie演示</h1>
<B>Result:</B> <%=res%><P><P>
</BODY>
</HTML>

4. 5使用C#调用
无需下载任何组件
Vi
sualà项目à新建 windows应用程序。àC#项目
在解决方案资源管理器中添加web引用,输入wsdl文件所在地址。
将web引用改名.
yundan.(service_name)即可引用
*需引用System.web.services*
例程:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using Syst
em.Data;
namespace csharp
{
        public class Form1 : System.Windows.Forms.Form
        {
            private System.Windows.Forms.Label label1;
            private System.Windows.Forms.TextBox textBox1;
            private System.ComponentModel.Container components = null;
            public Form1()
            {
                InitializeComponent();
            }
            protected override void Dispose( bool disposing )
            {
                if( disposing )
                {
                    if (components != null)
                    {
                        components.Dispose();
                    }
                }
                base.Dispose( disposing );
            }
            #region Windows Form Designer generated code
            private void InitializeComponent()
            {
                this.label1 = new System.Windows.Forms.Label();
                this.textBox1 = new System.Windows.Forms.TextBox();
                this.SuspendLayout();
                this.label1.AutoSize = true;
                this.label1.Location = new System.Drawing.Point(88, 48);
                this.label1.Name = "label1";
                this.label1.Size = new System.Drawing.Size(91, 14);
                this.label1.TabIndex = 0;
                this.label1.Text = "Webservice
演示";
                this.textBox1.Location = new System.Drawing.Point(88, 128);
                this.textBox1.Name = "textBox1";
                this.textBox1.TabIndex = 1;
                this.textBox1.Text = "textBox1";
                this.AutoScaleBa
seSize = new System.Drawing.Size(6, 14);
                this.ClientSize = new System.Drawing.Size(292, 273);
                this.Controls.AddRange(new System.Windows.Forms.Control[]
{
                this.textBox1,
                this.label1
});
                this.Name = "Form1";
                this.Text = "C#Webservie
演示";
                this.Load += new System.EventHandler(this.Form1_Load);
                this.ResumeLayout(false);
            }
            #endregion
            [STAThread]
            static void Main()
            {
                Application.Run
(new Form1());
            }

            private void Form1_Load(object sender, System.EventArgs e)
            {
                int str;
                你的web引用的名字.Service1 cc=new 你的web引用的名字.Service1();
                str=cc.test(123,324);
             
   textBox1.Text=str.ToString();
            }
        }
}

 

4.6(javascript)

需下载msSoapToolkit20.exe
引用:MSSOAP.SoapClient
    例程:
var WSDL_URL = "
http://192.168.0.4/yundan/service1.wsdl"
WScript.echo("
Connecting: " + WSDL_URL)
var Calc = WScript.CreateObject("MSSOAP.SoapClient")
Calc.mssoapinit(WSDL_URL, "", "", "")
var Answer
Answer = Calc.test(14,28)
WScript.Echo("14+28=" + Answer)
将其存成domo.js文件,直接双击运行。

4.7使用vb.net调用
无需下载任何组件
Visual
à项目à新建 windows应用程序。àBasic项目
在解决方案资源管理器中添加web引用,输入wsdl文件所在地址。
将web引用改名为yundan.
yundan.(service_name)即可引用
*需引用System.web.services*
例程:
    Public Class Form1
        Inherits System.Windows.Forms.Form
#Region " Windows 窗体设计器生成的代码 "
    Public Sub New()
        MyBase.New()
   
     InitializeComponent()
    End Sub
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub
    Private components As System.ComponentModel.IContainer
    Friend WithEvents Label1 As System.Windows.Forms.Label
    Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.Label1 = New System.Windows.Forms.Label()
        Me.TextBox1 = New System.Windows.Forms.TextBox()
        Me.SuspendLayout()
        Me.Label1.AutoSize = True
        Me.Label1.Location = New System.Drawing.Point(96, 40)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(91, 14)
        Me.Label1.TabIndex = 0
        Me.Label1.Text = "Webservice
演示"
        Me.TextBox1.Location = New System.Drawing.Point(88, 144)
        Me.TextBox1.Name = "TextBox1"
        Me.TextBox1.TabIndex = 1
        Me.TextBox1.Text = "TextBox1"
        Me.AutoScaleBaseSize = New System.Drawing.Size(6, 14)
        Me.Clien
tSize = New System.Drawing.Size(292, 273)
        Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.TextBox1, Me.Label1})
        Me.Name = "Form1"
        Me.Text = "VB.net webserive演示"
        Me.ResumeLayout(False)
    End Sub
#End Region
   
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim cc As yundan.Service1 = New yundan.Service1()
        TextBox1.Text = cc.test(12, 123)
    End Sub
End Class

4.8使用vb6.0调用
需下载msSoapToolkit20.
exe
添加引用:Microsoft Soap Type Library
位置:”C:\Program Files\Common Files\MSSoap\Binaries\ MSSOAP1.dll”
    调用方法:
    Dim cc As New MSSOAPLib.SoapClient
    例程:
    添加一个button控件Command1
à添加3个textbox控件,text1,text2,text3à标准EXEà新建工程
    代码如下:
    Option Explicit

Dim cc As New MSSOAPLib.SoapClient
Private Sub Command1_Click()
cc.mssoapinit "
http://192.168.0.4/yundan/Service1.asmx?WSDL"
Me.Text3.Text = cc.test(CInt(Text1.Text), CInt(Text2.Text))
End Sub
4
.9使用vbscript调用
需下载msSoapToolkit20.exe
引用:MSSOAP.SoapClient
    例程:
Option Explicit
Const WSDL_URL = "
http://192.168.0.4/yundan/service1.wsdl"
WScript.echo "Connecting: " & WSDL_URL
Dim Calc
Set Calc =
CreateObject("MSSOAP.SoapClient")
Calc.mssoapinit WSDL_URL
Dim Answer
Answer = Calc.test(14,28)
WScript.Echo "14+28=" & Answer
将其存成domo.vbs文件,直接双击运行。

4.10使用vc调用
需下载msSoapToolkit20.exe
    引用
#import "msxml3.dll"
using namespace MSXML2;
#import "C:\Progra
m Files\Common Files\MSSoap\Binaries\mssoap1.dll" exclude("IStream", "ISequentialStream", "_LARGE_INTEGER", "_ULARGE_INTEGER", "tagSTATSTG", "_FILETIME") raw_interfaces_only
using namespace MSSOAPLib;
例程:
新建工程àMFC AppWizard(exe)[ Mclient]àstep1à基本对话à其他默认值即可
修改源文件:
< StdAfx.h>
// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//

#if !defined(AFX_STDAFX_H__045CD307_9518_4AF1_8CE3_8FFE38D1ACB2__INCLUDED_)
#define AFX_STDAFX_H__045CD307_9518_4AF1_8CE3_8FFE38D1ACB2__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define VC_EXTRALEAN        // Exclude rarely-used stuff from Windows headers

#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxdisp.h>        // MFC Automation classes
#include <afxdtctl.h>       // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>         // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT

 

#import "msxml3.dll"
using namespace MSXML2;

#import "C:\Program Files\Common Files\MSSoap\Binaries\mssoap1.dll" exclude("IStream", "ISequentialStream", "_LARGE_INTEGER", "_ULARGE_INTEGER", "tagSTATSTG", "_FILETIME") raw_interfaces_only
using namespace MSSOAPLib;


#define MSG(message) \
{ \
    ::MessageBox(NULL,_T(message),NULL,MB_OK | MB_ICONEXCLAMATION| MB_APPLMODAL);\
    goto cleanup; \
}


#define CHECK_HRESULT(hr, message) \
if (FAILED(hr)) \
{ \
    MSG(message); \
}


//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__045CD307_9518_4AF1_8CE3_8FFE38D1ACB2__INCLUDED_)
<MClient.h>
// MClient.h : main header file for the MCLIENT application
//

#if !defined(AFX_MCLIENT_H__9A397DA6_5A62_4AEF_BE5E_6C7629322ECC__INCLUDED_)
#define AFX_MCLIENT_H__9A397DA6_5A62_4AEF_BE5E_6C7629322ECC__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef __AFXWIN_H__
    #error include 'stdafx.h' before including this file for PCH
#endif

#include "resource.h"       // main symbols

/
// CMClientApp:
// See MClient.cpp for the implementation of this class
//

class CMClientApp : public CWinApp
{
public:
    CMClientApp();

// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CMClientApp)
    public:
    virtual BOOL InitInstance();
    /

<MClientDlg.h>
    // MClientDlg.h : header file
//

#if !defined(AFX_MCLIENTDLG_H__C2D8DBC4_30FE_40DD_848C_78D5834CAD07__INCLUDED_)
#define AFX_MCLIENTDLG_H__C2D8DBC4_30FE_40DD_848C_78D5834CAD07__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

/
// CMClientDlg dialog

class CMClientDlg : public CDialog
{
// Construction
public:
    void EnableButtons();
    void DisableButtons();
    void AssignpRef(VARIANT *var1, VARIANT *var2);
    void assignItem(LVITEM *item, UINT mask, int iItem, int iSubItem, LPTSTR pszText, int cchTextMax);
    int UpdateList();
    bool DestroyTree();
    int CheckforURL();
    int ModifyDialog();
    void Execute();
    int nCountParameter();
    HTREEITEM AddtoTree(HTREEITEM hParent, HTREEITEM hInsertAfter, LPTSTR pszData, UINT mask, IUnknown * theInterface);
    CMClientDlg(CWnd* pParent = NULL);    // standard constructor

// Dialog Data
    //{{AFX_DATA(CMClientDlg)
    enum { IDD = IDD_MCLIENT_DIALOG };
    CTreeCtrl    m_TreeCtrl;
    CListCtrl    m_Parameters;
    CString    m_strParameter;
    CString    m_strURL;
    /

< MClientDlg.cpp>
    // MClientDlg.cpp : implementation file
//
#include "stdafx.h"
#include "MClient.h"
#include "MClientDlg.h"
#include "Atlbase.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CMClientDlg dialog

CMClientDlg::CMClientDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CMClientDlg::IDD, pParent)
{
    //{{AFX_DATA_INIT(CMClientDlg)
    m_strParameter = _T("");
    m_strURL = _T("");
    /

//
//  function: CMClientDlg::Execute()
//
//  parameters: No Parameters
//
//  description: Pass the parameters and invoke the operation, get the result and update the
//               parameters and the result value
//  returns: void
//
//
void CMClientDlg::Execute()
{
    USES_CONVERSION;

    DisableButtons();

    HTREEITEM                hItem;
    HTREEITEM                hPort;
    HTREEITEM                hService;

    DISPPARAMS                parms;
   
    VARIANT                    result;
    VARIANT                    vTempVariable;

    CComPtr<ISOAPClient>    pClient             =    NULL;
    HRESULT                 hr                 =    S_OK;

    BSTR                    bstrPort         =  0;
    BSTR                    bstrService      =  0;
    BSTR                    bstrWSDLFileName =  0;
    BSTR                    bstrWSMLFileName =  0;

    LVITEM                    Item;
    LVITEM                    Item1;

    int                        nNumParameters;
    int                        nCounter;
    int                        nCount;
   
    DISPID                    dispidFn;
   
    WCHAR                    *pstrFunctionName;

    char                     name[1024] ;

    EXCEPINFO               excepinfo;

    VARTYPE                 vt               =  VT_EMPTY;

    hItem                    =    m_TreeCtrl.GetSelectedItem();
       dispidFn                =    0;

    excepinfo.wCode               = 1001;
    excepinfo.wReserved           = 0;
    excepinfo.bstrSource          = 0;
    excepinfo.bstrDescription     = 0;
    excepinfo.bstrHelpFile        = 0;
    excepinfo.dwHelpContext       = 0;
    excepinfo.pvReserved          = 0;
    excepinfo.pfnDeferredFillIn   = 0;
    excepinfo.scode               = 0;
   
    VARIANT                 variantbstrtemp;
    VARIANT                    *pArg = 0;
    VARIANT                    *pRef = 0;

    smIsInputEnum           IsInput;

    nNumParameters          =   nCountParameter();

    if (nNumParameters != -1)
    {
        pArg = new VARIANT[nNumParameters];
        pRef = new VARIANT[nNumParameters];
    }
    else
        MSG("Could not get parameters from parameter list!");

    if ((!pArg) ||  (!pRef))
        MSG("There is no enough memory!");


    if (m_TreeCtrl.ItemHasChildren(hItem))
        MSG("Please select an operation!");

 


    hr    =  CoCreateInstance(__uuidof(SoapClient), NULL, CLSCTX_INPROC_SERVER, __uuidof(ISOAPClient),
                            (void **)&pClient);
    CHECK_HRESULT(hr, "Can not create the  object of the CLSID_SoapClient");


    if (!pClient)
        MSG("Can not create the  object of the CLSID_SoapClient!");


    // we need to have wsdl file and port and service name for mssoapinit
       hPort  = m_TreeCtrl.GetParentItem(hItem);
    if (!hPort)
        MSG("Can not get Port!");
   
    bstrPort = m_TreeCtrl.GetItemText(hPort).AllocSysString();
    if (bstrPort == NULL)
        MSG("Can not get Port Name!");

   
    hService = m_TreeCtrl.GetParentItem(hPort);
    if (!hService)
        MSG("Can not get Service !");
   
    bstrService = m_TreeCtrl.GetItemText(hService).AllocSysString();
    if (bstrService == NULL)
        MSG("Can not get Service Name!");


    bstrWSDLFileName =  m_strURL.AllocSysString();
    if (bstrWSDLFileName == NULL)
        MSG("Can not get WSDL file Name!");

    hr = pClient->mssoapinit(bstrWSDLFileName,bstrService,bstrPort,bstrWSMLFileName);
    CHECK_HRESULT(hr, "Soap initiation failed");

    // get the selected functions name
    pstrFunctionName     =    m_TreeCtrl.GetItemText(hItem).AllocSysString();
    if (pstrFunctionName == NULL)
        MSG("Could not get function Name!");

    parms.cArgs                = nNumParameters ;
    parms.cNamedArgs        = 0;
    parms.rgdispidNamedArgs = 0;
    //there is a pass by ref, and I  will use pRef as parameter list
    parms.rgvarg            = pRef;

    ::VariantInit(&result);
    ::VariantInit(&vTempVariable);

    nCount = 0;
    // the loop
should be 'number of parameters' times
    for (nCounter=0; nCounter < m_Parameters.GetItemCount()  ; nCounter ++)
    {
        // I need to get the value of parameter and its type
        assignItem(&Item, LVIF_PARAM,nCounter,0,0,0);
        assignItem(&Item1, LVIF_TEXT,nCounter,2,name,sizeof(name));

        if (m_Parameters.GetItem(&Item) == 0)
            MSG("Could not get item!");
        if (m_Parameters.GetItem(&Item1) == 0)
            MSG("Could not get item!");
       
        // we will not fill the arguments with result
        reinterpret_cast<ISoapMapper *>(Item.lParam)->get_isInput(&IsInput);
        if (IsInput != smOutput)
        {
            ::VariantInit(&pArg[nCount]);
            // I have to fill this array in reverse order bacause the server expects it in reverse order
            ::VariantInit(&pRef[nNumParameters - nCount -1]);

            // I keep the parameter as BSTR
            vTempVariable.vt = VT_BSTR;
            vTempVariable.bstrVal = ::SysAllocString(A2W(Item1.pszText));

            // the conversion for type and value of parameter is done
            // the value  with correct type and value is  taken into pArg
            long    ltype;
           
            hr = (reinterpret_cast<ISoapMapper*>(Item.lParam))->get_variantType(&ltype);
            CHECK_HRESULT(hr, "Could not get Variant Type");

            hr = ::VariantChangeType(&pArg[nCount],&vTempVariable,VARIANT_NOUSEROVERRIDE, (unsigned short) ltype);
            CHECK_HRESULT(hr, "Can not convert Variant Type! Either no Function selected or Parameter is Wrong or Empty");
           
            ::VariantClear(&vTempVariable);
            // assign the correct parameter to pRef and indicate it is BYREF
            pRef[nNumParameters - nCount -1 ].vt      = pArg[nCount].vt | VT_BYREF;
            AssignpRef(&pRef[nNumParameters - nCount -1],&pArg[nCount]);
            nCount ++;
        }
    }
 
    // get the ID of operation
    hr    =  pClient->GetIDsOfNames(IID_NULL, &pstrFunctionName, 1, LOCALE_SYSTEM_DEFAULT, &dispidFn);
    CHECK_HRESULT(hr, "Taking IDs Failed!");

    // calling the operation
    ::VariantClear(&result);

    hr    =  pClient->Invoke(dispidFn, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &parms,
                            &result, &excepinfo, 0);
    CHECK_HRESULT(hr, "Function call Failed!");

    ::VariantInit(&variantbstrtemp);

    // update the results

    for(nCounter = 0; nCounter <  m_Parameters.GetItemCount() ; nCounter++)
    {
        if (nCounter < nNumParameters)
        {
            hr = ::VariantChangeType(&variantbstrtemp,&pArg[nCounter],VARIANT_NOUSEROVERRIDE,VT_BSTR);
        }
        else
        {
            hr = ::VariantChangeType(&variantbstrtemp,&result,VARIANT_NOUSEROVERRIDE,VT_BSTR);
        }

        CHECK_HRESULT(hr, "Variant could not be converted");

        CString Text(variantbstrtemp.bstrVal);
        assignItem(&Item, LVIF_TEXT,nCounter,2, (LPTSTR)(LPCTSTR)Text,::SysStringLen(variantbstrtemp.bstrVal));

        if (m_Parameters.SetItem(&Item) == 0)
            MSG("Could not set Item to list");  
    }

    UpdateData(false);
   
cleanup:
    for(nCounter = 0; nCounter < nNumParameters ; nCounter++)
    {
        ::VariantClear(&pArg[nCounter]);
        ::VariantClear(&pRef[nCounter]);
    }

    ::VariantClear(&result);
    ::VariantClear(&variantbstrtemp);
    ::VariantClear(&vTempVariable);
    ::SysFreeString(bstrPort);
    ::SysFreeString(bstrService);
       ::SysFreeString(bstrWSDLFileName);
   
    if (pArg)
        delete [] pArg;
    if (pRef)
        delete [] pRef;

    EnableButtons();
    return;
}

//
//  function: CMClientDlg::OnDeleteitemListparam()
//
//  parameters: (NMHDR* pNMHDR, LRESULT* pResult)
//
//  description: for each row of list, it calls the Release
//
//  returns: void
//
//
void CMClientDlg::OnDeleteitemListparam(NMHDR* pNMHDR, LRESULT* pResult)
{
// We have to release lParam that I filled with object of ISoapMapper
    NMLISTVIEW   *tempVar = (NMLISTVIEW*)pNMHDR;;

    if (reinterpret_cast <IUnknown*>(tempVar->lParam))
        (reinterpret_cast <IUnknown*>(tempVar->lParam))->Release();
   
    *pResult = 0;
}

//
//  function: CMClientDlg::OnDeleteitemTree()
//
//  parameters: (NMHDR* pNMHDR, LRESULT* pResult)
//
//  description: for each tree elements, it calls the Release method
//  returns: void
//
//
void CMClientDlg::OnDeleteitemTree(NMHDR* pNMHDR, LRESULT* pResult)
{
    // We have to release lParam that I filled with object
    NMTREEVIEW   *tempVar = (NMTREEVIEW*)pNMHDR;;
    if (reinterpret_cast <IUnknown*>(tempVar->itemOld.lParam))
        (reinterpret_cast <IUnknown*>(tempVar->itemOld.lParam))->Release();

    *pResult = 0;
}

//
//  function: CMClientDlg::OnSelchangedTree()
//
//  parameters: (NMHDR* pNMHDR, LRESULT* pResult)
//
//  description: for selection on tree, it updates the list
//
//  returns: void
//
//
void CMClientDlg::OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult)
{
    // if the selected is operation, update the list with its parameters
    NMTREEVIEW* pNMTreeView = (NMTREEVIEW*)pNMHDR;


    IUnknown *pUnk = reinterpret_cast<IUnknown *>(pNMTreeView->itemNew.lParam);

    if (! pUnk)
        return;

    IWSDLOperation *pOper = 0;

    m_strParameter.Empty();
    UpdateData(false);

    if(SUCCEEDED(pUnk->QueryInterface(__uuidof(IWSDLOperation), reinterpret_cast<void **>(&pOper))))
    {
        if (UpdateList() != 1)
            MSG("Parameter list can not be created!");
    }

    *pResult = 0;

cleanup:
    if (pOper)
        pOper->Release();
   
    return;
}
/
//  function: CMClientDlg::OnLoad()
//
//  parameters: No Parameters
//
//  description:  takes the service, ports and operations and fills the tree
//
//  returns: void
//
/
void CMClientDlg::OnLoad()
{
    USES_CONVERSION;

    UpdateData(true);
// chech if wsdl file is given, if not, return
    if (CheckforURL() == -1)
        return;

// delete the tree if exist, if a tree exist and cant be deleted, return
    if (!DestroyTree())
        return;

    HRESULT                            hr                        =    S_OK;

    BSTR                            bstrWSDLFileName        =   0;
    BSTR                            bstrServiceName            =    0;
    BSTR                            bstrPortName            =    0;
    BSTR                            bstrOperationName        =    0;
    int                             flag                    =   1;
    int                             flag_SERVICE            =   0;
    int                             flag_PORT               =   0;
    int                             flag_OPERATION          =   0;

    CComPtr<IEnumWSDLService>        pIEnumWSDLServices;
    CComPtr<IEnumWSDLPorts>            pIEnumWSDLPorts;
    CComPtr<IEnumWSDLOperations>    pIEnumWSDLOps;
    CComPtr<IWSDLOperation>            pIOperation;
    CComPtr<IWSDLReader>            pIWSDLReader;
    CComPtr<IWSDLService>            pIWSDLService;
    CComPtr<IWSDLPort>                pIWSDLPort;

    long                            cFetched;

    HTREEITEM                        hSERVICE;
    HTREEITEM                        hPORT;
    HTREEITEM                        hOPERATION;

    // take the name of wsdl file
    bstrWSDLFileName =  m_strURL.AllocSysString();

    if (bstrWSDLFileName == NULL)
        return;

    hr = CoCreateInstance(__uuidof(WSDLReader), NULL, CLSCTX_INPROC_SERVER, __uuidof(IWSDLReader),
                        (void**)&pIWSDLReader);
    CHECK_HRESULT(hr, "Can not create the  object of the CLSID_WSDLReader");

    // loading needs wsdl and wsml files, but I dont know wsml file and I pass ""
    hr = pIWSDLReader->Load(bstrWSDLFileName, L"");   
       CHECK_HRESULT(hr, "Loading WSDL and WSML files failed!");

    // get soap service
    hr = pIWSDLReader->GetSoapServices(&pIEnumWSDLServices);
    CHECK_HRESULT(hr, "Can not get Services");

    if (!pIEnumWSDLServices)
        MSG("Can not get Services");

    while((hr = pIEnumWSDLServices->Next(1, &pIWSDLService, &cFetched)) == S_OK)
    {
        // at least one time this loop should go inside; if it does not, the flag wont be updated
        // so we can not continue and should destroy the tree if any part created
        flag_SERVICE   =   1;
        // get service name
        hr = pIWSDLService->get_name(&bstrServiceName);
        CHECK_HRESULT(hr, "Can not get Service names");

        // add the name of service in to tree
        // first field is NULL, it means insert this as root
        hSERVICE= AddtoTree(NULL,TVI_SORT,W2A(bstrServiceName),TVIF_TEXT,pIWSDLService);
        ::SysFreeString(bstrServiceName);
        if (!hSERVICE)
        {
            flag = 0;
            goto cleanup;
        }

        hr = pIWSDLService->GetSoapPorts(&pIEnumWSDLPorts);
        CHECK_HRESULT(hr, "Can not get Ports");

        if (!pIEnumWSDLPorts)
            MSG("Can not get Ports");

        while((hr = pIEnumWSDLPorts->Next(1,&pIWSDLPort, &cFetched)) == S_OK)
        {
            // at least one time this loop should go inside; if it does not, the flag wont be updated
            // so we can not continue and should destroy the tree if any part created
            flag_PORT  =   1;
             // get port name
            hr = pIWSDLPort->get_name(&bstrPortName);
            CHECK_HRESULT(hr, "Can not get Port names");

            // add to tree but as a child of SERVICE
            hPORT= AddtoTree(hSERVICE,TVI_SORT,W2A(bstrPortName),TVIF_TEXT,pIWSDLPort);
            ::SysFreeString(bstrPortName);
            if (!hPORT)
            {
                flag = 0;
                goto cleanup;
            }

            hr = pIWSDLPort->GetSoapOperations(&pIEnumWSDLOps);
            CHECK_HRESULT(hr, "Can not get Operations");
            if (!pIEnumWSDLOps)
                MSG("Can not get Operations");

            while((hr = pIEnumWSDLOps->Next(1,&pIOperation, &cFetched)) == S_OK)
            {
             // at least one time this loop should go inside; if it does not, the flag wont be updated
             // so we can not continue and should destroy the tree if any part created
                flag_OPERATION  =   1;

                hr = pIOperation->get_name(&bstrOperationName);
                CHECK_HRESULT(hr, "Can not get Operation names");

                hOPERATION= AddtoTree(hPORT,TVI_SORT,W2A(bstrOperationName),TVIF_TEXT,pIOperation);
                ::SysFreeString(bstrOperationName);
                if (!hOPERATION)
                {
                    flag = 0;
                    goto cleanup;
                }
                // we do release by assigning to 0
                pIOperation= 0;
            }
            if (flag_OPERATION == 0)
            {
                flag =0;
                MSG("Could not load  OPERATIONS!");
            }
            we do release by assigning to 0
            pIWSDLPort = 0;
        }
        if (flag_PORT == 0)
        {
            flag =0;
            MSG("Could not load  PORTS!");
        }
        we do release by assigning to 0
        pIWSDLService = 0;
    }
   
    if (flag_SERVICE == 0)
    {
        flag =0;
        MSG("Could not load  SERVICE!");
    }
    UpdateData(false);

cleanup:
    ::SysFreeString(bstrWSDLFileName);
       ::SysFreeString(bstrServiceName);
    ::SysFreeString(bstrPortName);
    ::SysFreeString(bstrOperationName);


    if (flag == 0)
        DestroyTree();

    return;
}

 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值