3.改变所调用的Web服务
这里我们将稍微改变在《Web服务初探:用Demo学Web服务系列(2)——编写一简单的Web服务》中建立的WebService,为了能让大家有所对比,我们将改变前后的代码都给出来。
先前建立的WebService如下:
这里还必须要说明的是一定要实例化SoapHeader,绝对不能在调用WebService的某个方法之后才给SoapHeader各个成员赋值,在调用之前至于是先绑定还是先赋值均可。下面是错误的编写顺序:
先前建立的WebService如下:
1
using System;
2
using System.Web;
3
using System.Web.Services;
4
using System.Web.Services.Protocols;
5![]()
6
[WebService(Namespace = "http://tempuri.org/")]
7
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
8
public class MyServiceClass : System.Web.Services.WebService
9
{
10
public MyServiceClass()
11
{
12
//如果使用设计的组件,请取消注释以下行
13
//InitializeComponent();
14
}
15![]()
16
[WebMethod]
17
public bool Login(string UserName,string PassWord)
18
{
19
if (UserName == "Micky" && PassWord == "micky0")
20
{
21
return true;
22
}
23
else
24
{
25
return false;
26
}
27
}
28
}
29![]()
using System;2
using System.Web;3
using System.Web.Services;4
using System.Web.Services.Protocols;5

6
[WebService(Namespace = "http://tempuri.org/")]7
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]8
public class MyServiceClass : System.Web.Services.WebService9
{10
public MyServiceClass()11
{12
//如果使用设计的组件,请取消注释以下行 13
//InitializeComponent(); 14
}15

16
[WebMethod]17
public bool Login(string UserName,string PassWord)18
{19
if (UserName == "Micky" && PassWord == "micky0")20
{21
return true;22
}23
else24
{25
return false;26
}27
} 28
}29

而改变后的代码:
1
using System;
2
using System.Web;
3
using System.Web.Services;
4
using System.Web.Services.Protocols;
5![]()
6
public class MyServiceClassHeader : SoapHeader
7
{
8
public string UsN;
9
public string PaW;
10
}
11
[WebService(Namespace = "http://tempuri.org/")]
12
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
13
public class MyServiceClass : System.Web.Services.WebService
14
{
15
public MyServiceClass()
16
{
17![]()
18
//如果使用设计的组件,请取消注释以下行
19
//InitializeComponent();
20
}
21![]()
22
public MyServiceClassHeader MSCH;
23![]()
24
[WebMethod]
25
[SoapHeader("MSCH",Direction = SoapHeaderDirection.In)]
26
public string Login()
27
{
28
if (MSCH != null)
29
{
30
if (MSCH.MustUnderstand)
31
{
32
string UserName = MSCH.UsN;
33
string PassWord = MSCH.PaW;
34
if (UserName == "Micky" && PassWord == "micky0")
35
{
36
return "登录成功!";
37
}
38
else
39
{
40
return "登录错误!";
41
}
42
}
43
else
44
{
45
return "消息头不是必懂的!";
46
}
47
}
48
else
49
{
50
return "无头消息!";
51
}
52
}
53
}
using System;2
using System.Web;3
using System.Web.Services;4
using System.Web.Services.Protocols;5

6
public class MyServiceClassHeader : SoapHeader7
{8
public string UsN;9
public string PaW;10
}11
[WebService(Namespace = "http://tempuri.org/")]12
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]13
public class MyServiceClass : System.Web.Services.WebService14
{15
public MyServiceClass()16
{17

18
//如果使用设计的组件,请取消注释以下行 19
//InitializeComponent(); 20
}21

22
public MyServiceClassHeader MSCH;23

24
[WebMethod]25
[SoapHeader("MSCH",Direction = SoapHeaderDirection.In)]26
public string Login()27
{28
if (MSCH != null)29
{30
if (MSCH.MustUnderstand)31
{32
string UserName = MSCH.UsN;33
string PassWord = MSCH.PaW;34
if (UserName == "Micky" && PassWord == "micky0")35
{36
return "登录成功!";37
}38
else39
{40
return "登录错误!";41
}42
}43
else44
{45
return "消息头不是必懂的!";46
}47
}48
else49
{50
return "无头消息!";51
}52
}53
} 大家可以看出来,我们使用了一个新的类MyServiceClassHeader,而这个新类继承自SoapHeader这个。在这个MyServiceClassHeader中我们定义了两个公共变量UsN和PaW,分别来存储用户名和密码。为了能帮助大家理解,我们简要的说明一下SoapHeader的用途,在Soap消息中可以包含一个消息的头,可以在这里添加并传递一些如用户名和密码等类似的简单数据,我们将在《系列》的后面介绍Soap消息的结构。在Login方法中还要多定义一个属性[SoapHeader("MSCH",Direction = SoapHeaderDirection.In)],这样我们就从消息头中取出了用户名和密码做验证并返回一个验证结果。(如果对其中的SoapHeader定义使用有什么问题请在评论中提出。)
在看C/S程序前,请运行编译一下我们改变后的MyServiceClass的这个Web服务。下面我们来看看在《Web服务初探:用Demo学Web服务系列(3)——用C/S程序调用Web服务》中的C/S程序中是如何再调用这个改变后的MyServiceClass。仍然用原来的代码和更改后的代码进行对比。
首先看原先的窗体代码:
1
using System;
2
using System.Collections.Generic;
3
using System.ComponentModel;
4
using System.Data;
5
using System.Drawing;
6
using System.Text;
7
using System.Windows.Forms;
8
9
namespace WindowsPro
10
{
11
public partial class Login : Form
12
{
13
public Login()
14
{
15
InitializeComponent();
16
}
17![]()
18
private void Btn_Login_Click(object sender, EventArgs e)
19
{
20
MyServ.MyServiceClass MyWebServ = new MyServ.MyServiceClass();
21
bool LoginOK = MyWebServ.Login(this.tB_UserName.Text, this.tB_PassWord.Text);
22
if (LoginOK)
23
{
24
MessageBox.Show("用户名和密码正确!");
25
}
26
else
27
{
28
MessageBox.Show("用户名和密码错误!");
29
}
30
}
31![]()
32
private void Btn_Close_Click(object sender, EventArgs e)
33
{
34
this.Close();
35
}
36
}
37
}
38![]()
using System;2
using System.Collections.Generic;3
using System.ComponentModel;4
using System.Data;5
using System.Drawing;6
using System.Text;7
using System.Windows.Forms;8
9
namespace WindowsPro10
{11
public partial class Login : Form12
{13
public Login()14
{15
InitializeComponent();16
}17

18
private void Btn_Login_Click(object sender, EventArgs e)19
{20
MyServ.MyServiceClass MyWebServ = new MyServ.MyServiceClass();21
bool LoginOK = MyWebServ.Login(this.tB_UserName.Text, this.tB_PassWord.Text);22
if (LoginOK)23
{24
MessageBox.Show("用户名和密码正确!");25
}26
else27
{28
MessageBox.Show("用户名和密码错误!");29
}30
}31

32
private void Btn_Close_Click(object sender, EventArgs e)33
{34
this.Close();35
}36
}37
}38

为了适合更改后的MyServiceClass,这个代码将改变为(首先要右击名为MyServ的代理类,选择“更新Web引用”):
1
using System;
2
using System.Collections.Generic;
3
using System.ComponentModel;
4
using System.Data;
5
using System.Drawing;
6
using System.Text;
7
using System.Windows.Forms;
8![]()
9
namespace WindowsPro
10
{
11
public partial class Login : Form
12
{
13
public Login()
14
{
15
InitializeComponent();
16
}
17![]()
18
private void Btn_Login_Click(object sender, EventArgs e)
19
{
20
MyServ.MyServiceClassHeader MyHeader = new MyServ.MyServiceClassHeader();
21
MyServ.MyServiceClass MyWebServ = new MyServ.MyServiceClass();
22
MyHeader.UsN = this.tB_UserName.Text;
23
MyHeader.PaW = this.tB_PassWord.Text;
24
MyHeader.MustUnderstand = true;
25
MyWebServ.MyServiceClassHeaderValue = MyHeader;
26
string LoginOK = MyWebServ.Login();
27
MessageBox.Show(LoginOK);
28
if (LoginOK == "登录成功!")
29
{
30
……
31
}
32
}
33![]()
34
private void Btn_Close_Click(object sender, EventArgs e)
35
{
36
this.Close();
37
}
38
}
39
}
using System;2
using System.Collections.Generic;3
using System.ComponentModel;4
using System.Data;5
using System.Drawing;6
using System.Text;7
using System.Windows.Forms;8

9
namespace WindowsPro10
{11
public partial class Login : Form12
{13
public Login()14
{15
InitializeComponent();16
}17

18
private void Btn_Login_Click(object sender, EventArgs e)19
{20
MyServ.MyServiceClassHeader MyHeader = new MyServ.MyServiceClassHeader();21
MyServ.MyServiceClass MyWebServ = new MyServ.MyServiceClass();22
MyHeader.UsN = this.tB_UserName.Text;23
MyHeader.PaW = this.tB_PassWord.Text;24
MyHeader.MustUnderstand = true;25
MyWebServ.MyServiceClassHeaderValue = MyHeader;26
string LoginOK = MyWebServ.Login();27
MessageBox.Show(LoginOK);28
if (LoginOK == "登录成功!")29
{30
……31
}32
}33

34
private void Btn_Close_Click(object sender, EventArgs e)35
{36
this.Close();37
}38
}39
}为了帮助大家理解给调用的方法添加SoapHeader的过程,我们来分析其中几个比较关键的代码,如下:
1
MyServ.MyServiceClassHeader MyHeader = new MyServ.MyServiceClassHeader();
2
MyServ.MyServiceClass MyWebServ = new MyServ.MyServiceClass();
3
MyHeader.UsN = this.tB_UserName.Text;
4
MyHeader.PaW = this.tB_PassWord.Text;
5
MyHeader.MustUnderstand = true;
6
MyWebServ.MyServiceClassHeaderValue = MyHeader;
7
string LoginOK = MyWebServ.Login();
8
MessageBox.Show(LoginOK);
首先我们要实例化WebService的SoapHeader类(第1行),然后给这个WebService的SoapHeader类中的各个成员赋值(第3行和第4行),第5行是说这个SoapHeader是否让WebService中的某个方法必须处理的(大家可以把值改为false运行后测试一下看看返回什么提示框),最关键的一句话是写使用SoapHeader必不可少的就是第6行,这句话是将这个实例化的SoapHeader具体绑定到一个WebService的某个类调用上,当调用绑定后的这个类时,就会在由代理类生成的Soap消息中将这个SoapHeader生成进去。之后就是我们前面介绍的调用WebService中的方法和显示返回值(第7行和第8行)。
MyServ.MyServiceClassHeader MyHeader = new MyServ.MyServiceClassHeader();2
MyServ.MyServiceClass MyWebServ = new MyServ.MyServiceClass();3
MyHeader.UsN = this.tB_UserName.Text;4
MyHeader.PaW = this.tB_PassWord.Text;5
MyHeader.MustUnderstand = true;6
MyWebServ.MyServiceClassHeaderValue = MyHeader;7
string LoginOK = MyWebServ.Login();8
MessageBox.Show(LoginOK);这里还必须要说明的是一定要实例化SoapHeader,绝对不能在调用WebService的某个方法之后才给SoapHeader各个成员赋值,在调用之前至于是先绑定还是先赋值均可。下面是错误的编写顺序:
1
MyServ.MyServiceClassHeader MyHeader = new MyServ.MyServiceClassHeader();
2
MyServ.MyServiceClass MyWebServ = new MyServ.MyServiceClass();
3![]()
4
MyHeader.MustUnderstand = true;
5![]()
6
MyWebServ.MyServiceClassHeaderValue = MyHeader;
7![]()
8
string LoginOK = MyWebServ.Login();
9
MyHeader.UsN = this.tB_UserName.Text;//错误位置
10
MyHeader.PaW = this.tB_PassWord.Text;//错误位置
11
MessageBox.Show(LoginOK);
第9行和第10行代码位置就是错了,不可能方法都从WebService执行完了才给SoapHeader各个成员赋值。而第9行和第10行的代码插入到第3行、第5行或者第7行,整个程序都是对的,你们说说对吗?(留给大家自己想原因吧,呵呵……)下一篇随笔我们就要建立一个Access数据库的用户表来做用户登录的验证了,请博友们继续关注吧。
MyServ.MyServiceClassHeader MyHeader = new MyServ.MyServiceClassHeader();2
MyServ.MyServiceClass MyWebServ = new MyServ.MyServiceClass();3

4
MyHeader.MustUnderstand = true;5

6
MyWebServ.MyServiceClassHeaderValue = MyHeader;7

8
string LoginOK = MyWebServ.Login();9
MyHeader.UsN = this.tB_UserName.Text;//错误位置10
MyHeader.PaW = this.tB_PassWord.Text;//错误位置11
MessageBox.Show(LoginOK);

