《C#高级编程(第四版)_OCRed_部分16.pdf》由会员分享,可在线阅读,更多相关《C#高级编程(第四版)_OCRed_部分16.pdf(61页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第28章Web服务.889.开发过程中不是问题,但以后应修改它。为此可以使用WebService属性,但目前不修改它。单击方法名称,可以得到SOAP请求和响应的信息,此外,还可以得到一个示例,通过该示例对如何通过HTTPGET和HTTPPOST方法获得请求和响应有一个感性的认识。另外,也可以单击Invoke按钮,对方法进行测试。如果方法需要简单的参数,在这个窗体中也可以输入它们(如果方法需要较复杂的参数,这个窗体就不允许以这种方式测试方法)。这样,就可以看到方法调用所返回的XML:Y es we can!这说明方法运行良好。单击图28-2的浏览器屏幕上的ServiceDescription链接
2、,可以查看Web服务的WSDL描述。其中最重要的部分是关于请求和响应的元素类型的描述:该描述比较长,除了包含服务的各种绑定之外,还可以包含请求和响应所需类型的描述。Web服务可以使用的类型Web服务可以用于交换表28-1中所示的类型。表28-1Strir Char Byte Boolean Int16 Int32 Int64 Ulnt16 Ulnt32 Ulnt64 Double Guid Decimal DateTime XmlOualifiedName Class struct XmlNode DataSet enum 以上所有类型的数组都可以使用,因为它们都是一般集合类型,例如List。
3、还要注意,只能编组Class和struct类型的公共属性和宇段。.890.第VI部分通信28.3.2 使用Web服务上面讨论了如何创建Web服务,接下来就讨论如何使用它们。为此需要在代码中生成一个知道如何与给定Web服务进行通信的代理类。这样,代码中对Web服务进行的任何调用都要通过这个代理类,从表面看,这个代理类就等同于Web服务,代码也会认为我们有了Web服务的本地副本。而实际的情况是有许多HTTP通信工作在进行,只是我们感觉不到其中的细节。有两种方式可以完成这项任务:第一,可以使用WSDL.exe命令行工具:第二,可以使用VS.NET中的AddWeb Reference菜单选项。在命令行
4、上使用WSDL.exe时,它会根据Web服务的WSDL描述生成一个包含代理类的.cs文件。使用Web服务的URL来指定该文件,例如:WSDL http:/localhost:61968IPCSWebSrv l/Service 1.asmx?WSDL 注意:这里和随后的例子使用默认的文件系统存储Web应用程序。为了使上面的URL起作用,必须给Web服务运行VisualWeb Developer Web Server。这仍不能保证Web服务的端口号(在这里是61968)是相同的。这适合于演示,因为一般我们希望Web服务位于固定的Web服务器,如IIS上,否则就必须重新生成代理类。确保Web服务可用
5、于测试的一种方式是在一个解决方案中包含多个Web站点。这样就会在Service.cs文件中为上一小节中的示例生成一个代理类。这个代理类将以Web服务命名,在这个示例中就是Service.该代理类包含一些方法,那些方法将可以调用与同名服务的方法。在使用这个类时,只需把所生成的.cs文件添加到项目中,使用下面的代码就可以了:Service myService=new ServiceO;String result=myService.CanWeFixItO;默认状态下,生成的类将放在根命名空间中,因此不需要使用using语句,但是,可以使用WSDL.exe命令行选项/n:指定一个不同的命名空间。这项
6、技术按说应该不错了,但是,如果服务正处于开发或处于连续变动中,就比较费事了。当然,为了在每次编译之前自动更新所生成的代理类,这项技术可以用项目的构建选项来执行,但是我们有更好的方法。下面在一个新的Web站点PCWebClientl中,为上一小节中的示例创建客户程序(在目录C:ProCSharpChapter 28下).来阐明这个更好的方法。现在创建这个新项目,在Default.aspx页面中,添加下面的代码:第28章Web服务 891 接下来将把单击按钮事件处理程序与Web服务绑定起来。首先需要在项目中添加对Web服务的引用。其方法是:右击SolutionExplorer中的新客户项目,选择A
7、ddWeb Reference选项。然后,在出现的窗口中键入Web服务文件Servicel.邵阳的URL,或者使用本地机器链接中的Web服务,自动查找它,如图28-3所示。NIVigIte to w曲胃晤时JtI.世d血剑割w.回国ocId.tho.s.Cl-0囹出L:The follo酬nooperations are suported.For formal definition,please rev iew恤.5ervi.:eOe.criD创on且A且旦旦flHItT11ls web servlce is uslng h吐p:lltempuri.orol.5 Its default nam
8、espa四.Recommendatlon:ChaRQB由edefault nameSpaC8 before 由oXML Wob 50,1田15m.cte pUbllc.e.cI、x阿LWeb servi由needsa unique namespace in order for:lGo dient applic础。nsto distinouish it from 0由.r皿阿国Son出eWeb h即:/ltempuri.orol陆刷刷ablefor X阿LWeb servi由,由atare under developme肘Ibut ublished X例Lweb S8阿t国5should use
9、 a w、。repem、anentna、espace,Your XML Web S8问iceshould be identi何时bya narnespace tt.at For examole.YOU四nuse yourmp.町sIntemet 图28-3W曲,唰幅r.m.眩目也LRI.,一1 5ervice Fcu晴:,、sor呐国v W回,.,田.:r 110.;.c.uI.J 接着,可以使用AddReference按钮添加引用。但应先把Web引用的默认内容从localhost改为myWebService 0现在单击AddReference按钮,在SolutionExplorer中把myW
10、ebService添加到项目的WebReferences文件夹,在SolutionExplorer中显示这个文件夹时,可以看到Service.disco、Service.discomap和Service1.wsdl己添加到项目中。Web引用名称myWebService也是使用代理类时需要引用的命名空间,在Default.aspx.cs的代码中添加下面的using语句:using myWebService;现在就可以在类中使用服务了,而不必提供服务的完全限定名称。使用下面的代码把事件处理程序添加给窗体上的按钮:private void triggerButton_Click(object sen
11、der,System.EventArgs e)Service myService=new ServiceO;resultLabel.Text=myService.CanWeFixItO;运行应用程序并且单击按钮,浏览器窗口中将显示CanWeFixltO的执行结果。.892 第VI部分通信注意:如果使用ASP.NETDevelopment Server(!P Web应用程序存储在本地文件系统上,而没有存储在lIS上),就会产生401:Unauthorized错误。这是因为,这个服务器配直为默认需要NTLM验证。为了更正这个错误,可以在PCSWebService 1属性页面的StartOption
12、s页面上取消NTLMAuthentication复选框的选择,或者在调用Web服务方法时传送默认的证书。后一种方式需要代码。myService.Credentias=System.Net.CredentialCache.DefaultCredentials;.以后这个Web服务也许会改变,但是,使用这个方法,可以简单地右击ServerExplorer中的WebReference文件夹,并选择UpdateWeb Reference,生成一个新的代理类以供使用。28.4 扩充会议登记示例现在我们己经对Web服务的创建和使用有了一定的了解,接下来要应用这些知识来扩充前两章中的会议登记应用程序。具体来
13、说,就是从应用程序中把数据库访问方面的内容提取出来,放到一个Web服务中。这个Web服务有两个方法:GetDataO,它返回一个DataSet对象,DataSet包含PCSWebApp3数据库中的3个表。AddEventO,它添加一个事件,返回受影响的行数,所以客户应用程序可以检查数据是否发生变化。此外,使用能够减少载入量的技术来设计Web服务。具体来说,就是把包含会议登记数据的DataSet保存在Web服务应用程序中的应用程序层上,这意味着对数据的多个请求将不需要进行额外的数据库请求工作。这样,只有在数据库中添加新的数据时,处于应用程序层DataSet中的数据才会被刷新。通过其他方式对数据库
14、的改变如手工编辑就不会在DataSet中反映出来。而且,只有使用Web服务才能直接访问数据,这样我们就没有什么可担心的了。28.4.1 会议登记Web服务在VS中,在C:ProCSharpChapter28目录下创建一个名为PCSWebSrv2的新Web服务项目。首先,复制PCSWebApp3(或PCSDemoSite)中的数据库文件MeetingRoomBooker.mdf和MeetingRoomBooker一log.ldf。接着给项目添加Global.as拙文件,在它的Application_ StartO事件处理程序中修改代码。把MeetingRoomBooker数据库中的所有数据都载入
15、到数据集中并且保存数据集,其中涉及的大部分代码前面己讨论过,因为前面已经把数据库载入到DataSet中。也可以使用存储在Web.config文件中的连接字符串。Web.config文件的代码如下所示(连接字符串应放在单独一行上):在Global.asax的Application_ StartO事件处理程序中,代码如下所示:void Application_Start(Object sender,EventArgs e)System.Data.DataSet ds;System.Data.SqlClient.SqlConnection sqlConnectionl;System.Data.Sql
16、Client.SqlDataAdapter daAttendees;System.Data.SqlClient.Sq1DataAdapter daRooms;System.Data.SqlClient.SqlDataAdapter daEvents;sqlConnection 1=Ilew System.Data.SqlClient.SqlConnectionO;sqlConnectionl.ConnectionString=ConfigurationManager.ConnectionStringsMRBConnectionString.ConnectionString;sqlConnect
17、ion 1.0penO;ds=new System.Data.DataSetO;daAttendees=new System.Data.SqIClient.SqlDataAdapter(SELECT FROM Attendees,sqlConnectionl);daRooms=new System.Data.SqlClient.sqlDataAdapter(SELECT FROM Rooms,sqlConnectionl);daEvents=new System.Data.SqIClient.SqIDataAdapter(SELECT*FROM Events,sqIConnectionl);d
18、aAttendees.FilI(ds,A忧endees);daRooms.FiIl(缸,Rooms);daEvents.FiI(ds,Events);sqlConnection 1.Close();Applicationds=ds;.893 这里需要注意代码中的最后二行。通常,Application(以及Session)对象都有一个名/值对的集合,可以在该集合中保存数据。这里在Application存储中创建一个名称ds,它从数据库中提取数据集ds的串行化值,其中包含数据库中的表Attendees、Rooms和Eventso这样,Web服务对象的所布实例在任何时间都可以访问ds中保存的值。这项
19、技术非常适合于只读数据,因为多个线程可以询问它,减少了对数据库中数据的载入。但要注意,由于Events表有可能发生变化,在Events表发生变化时,必须更新应用程序层.894.第VI部分通信DataSet。稍后会介绍这一内容。接下来用一个新的服务MRBService替换默认的Service服务。为此,删除己育的Service.asmx和Service.cs文件,在项目中添加个新的Web服务MRBService。接着把方法GetDataO添加给MRBService.cs中的服务:WebMethod public DataSet GetDataO return(DataSet)Applicatio
20、nds;上面代码使用与Application_ LoadO相同的语法来访问存储的DataSet,这样,就可以简单地将数据转换为正确的类型,并返回。为了使上述代码正常工作,井便于以后添加的其他Web方法正常工作,可以添加下面的using 语句:using System;using System.Configuration;using System.Data;using System.Web;using System.Collections;using System.Web.Services;using System.Web.Services.Protocols;AddEventO方法稍微有点复杂
21、,从概念上讲,需要做下面的事情:接受来自客户的事件数据。使用那些数据创建SQLINSERT语句。连接数据库并且执行SQL语句。如果添加成功,就需要刷新Applicationds中的数据。把成功或失败的通知返回给客户(如果有必要,允许客户刷新他们的DataSet)。从现在开始,就要接收正确数据类型的宇段:WebMethod public int AddEvent(String eventName,int eventRoom,String eventAttendees,DateTime eventDate)下面声明访问数据库、连接数据库以及执行查询时需要的对象,完成这些工作所使用的代码与PCSWe
22、bApp3中的代码相似(此外,这里也需要连接字符串,从Web.config中提取):WebMethod public int AddEvent(String eventName,int eventRoom,String eventAttendees,DateTime eventDate)第28章Web服务System.Data.SqIClient.SqIConnection sqlConnection 1;System.Data.SqIClient.SqIDataAdapter daEvents;DataSet ds;sqlConnectionl=new System.Data.SqIClie
23、nt.SqIConnection();sqlConnection I.ConnectionString=Confi币fig引ur刚a刽蚓tionMa肌na咆.ge缸r.Conne邱蚓c创ti讪on崎1岱St创rdiIn吨I咆gs副s叫可咄.ConnectionString;System.Data.SqlClient.SqlCommand insertCommand=new System.Data.SqIClient.SqICommand(INSERT INTO Events(Name,Room,+飞ttendeeList,EventDat功VALUES(Name,Room,AttendList
24、,+EventDate),sqlConnection 1);insertCommand.Parameters.Add(Name,SqlDbType.VarChar,255).Value=eventName;insertCommand.Parameters.Add(Room,SqlDbType.Int,4).V a1ue=eventRoom;insertCommand.Parameters.Add(AttendeeList,SqlDb Type.Text,16).Value=eventAttendees;insertCommand.Parameters.Add(EventDate,SqlDbTy
25、pe.DateTime,8).Value=eventDate;sq IConnection I.Open();int queryResult=insertComrnand.ExecuteNonQuery();.895.如以前一样,使用queryResult保存受查询影响的行数。如果queryResult的结果是1,则说明查询成功,然后就可以对数据库进行新的查询,以便刷新DataSet中的Events表。在执行更新时,必须把应用程序数据加锁,确保在更新过程中其他线程不可以访问Applicationds。使用Application对象的LockO和UnlockO方法,可以实现对数据的加锁和解锁zW
26、ebMethod public int AddEvent(String eventName,int eventRoom,String eventAttendees,DateTime eventDate)int queryResult=insertCommand.ExecuteNonQuery();if(queryResult-1)daEvents=new System.Data.SqlClient.SqlDataAdapter(SELECT FROM Events,sqIConnectionl);896 第VI部分通信ds=(DataSet)Applicationds;ds.TablesEve
27、nts.Clear();daEvents.Fil(ds,Events);Application.Lock();Application飞s=ds;Application.UnLock();sqlConnection 1.CloseO;最后,返回queryResult,以便让客户知道查询是否成功zWebMethod public int AddEvent(String eventName,int eventRoom,String eventAttendees,DateTime eventDate).return queryResult;至此,就完成了Web服务的编写。如同以前,可以对Web服务进行
28、测试,测试的方法就是在Web浏览器中查看.asmx文件,这样,不用编写任何客户机代码,就可以舔加记录,查看由GetDataO返回的DataSet的XML表示。在继续之前,需要讨论DataSet对象和Web服务的组合使用。初看起来这似乎是交换数据的一种荒谬方式,而实际上这是一种极其有用的技术。DataSet类的用途非常广泛,如果查看为GetDataO方法生成的WSDL.就会看到如下内容:可以看出,这是非常一般的代码,允许传送进来的DataSet对象包含用内联模式指定的任何数据。但是,这表示WSDL没有完整地描述Web服务。对于.NET客户这不是个问题,在前面的示例中传送简单的字符串时,一切都很正
29、常,惟一的区别是我们交换了一个DataSet对象。第28章Web服务.897.但是,非.NET客户必须提前了解要传送的数据,或者某个等价的DataSet类,才能访问数据。这个问题的解决方法是把数据重新封装为另一种格式,例如结构数组。如果这么做,就可以以任意方式定制生成的XML,XML可以由Web服务的模式完整地描述。这还可以提高性能,因为传送DataSet对象会生成大量的XML,在大多数情况下远远超过了需要的XML。重新打包数据导致的系统开销比在Web上传送数据的开销少得多,而且数据较少,串行化和并行化也较快。所以如果性能比较重要,就应避免以这种方式使用DataSet对象,除非要使用DataS
30、et对象提供的其他功能。但是,这里使用DataSet对象不会出问题,而且还可以大大简化其他代码。28.4.2 会议登记客户程序本节使用的客户程序是上一章开发的Web站点PCSDemoSite。下面把这个应用程序命名为PCSDemoSite2,放在C:ProCSharpChapter28目录下,并且使用PCSDemoSite中的代码作为起点。对项目主要进行两方面的修改:第一,从应用程序中删除对数据库直接访问的部分,并使用Web服务代替;第二,引入一个Web服务返回的DataSet的应用程序层存储器,并且只有在必要时才对DataSet进行更新,这意味着将大大降低数据库的负担。对于新的Web应用程序
31、来说,首先需要添加对PCSWebService2/MRBService.asmx服务的Web引用。添加的方法在本章的前面部分中已经讨论过,即在Se凹erEcplorer中右击项目,定位.asmx文件,调用Web引用MRBService,单击AddReference。我们不再使用本地数据库,所以还可以从App_Data目录中删除它,从Web.config中删除MRBConnectionStringJ页。开始时,删除MRB.ascx上的所有数据源,删除当前所有数据绑定控件上的DataSourceIDI页。这是因为我们要在后台代码文件中处理数据绑定。注意:在修改或删除Web服务器拉件的DataSou
32、rceID属性时,需要确认是否要删除已定义的模板,因为不能保证控件使用的数据对于这些模板来说仍旧有效。这里要使用原来的数据,只是从另一个数据源中提取,所以应保留模板。如果删除了模板,则HTML布局就会变成默认布局,看起来不漂亮,必须从头添加它们或重新编写它们。接着,需要给MRB.ascx.cs添加一个属性,以存储Web服务返回的DataSet。这个属性使用Application状态存储器,其方式与Web服务中的Global.asax相同。代码如下:public DataSet岛佩BDataget if(ApplicationmrbData-null)Application.LockO;MRBS
33、ervice.MRBService service=new MRBServi岛但BServiceO;service.Credentials=System.Net.CredentialCache.DefaultCredentials;.898.set 第VI部分通信ApplicationmrbData=service.GetDataO;Application.UnLockO;retum AppIicationmrbData as DataSet;Application.LockO;if(value nul&ApplicationmrbData!=null)Application.Remove(m
34、rbData);else ApplicationmrbData=value;Application.UnLockO;注意,需要加锁和解锁Application状态,这与Web服务中相同。另外。只有在需要时才填充ApplicationmrbData存储器,即在它为空时填充。这个DataSet对象现在可用于PCSDemoSite2的所有实例,也就是说多个用户可以读取数据,而无需调用Web服务或访问数据库。这里还设置了证书,如前所述,在使用ASP.NET Development Server中的Web服务时需要证书。如果不需要它,可以注释掉这行代码。要绑定Web页面上的控件,可以提供DataView
35、属性,它映射到存储在这个属性中的数据,如下所示:private DataView EventData get retum MRBData.TablesEvents.DefaultView;private DataView RoomData get retum MRBData.TablesRooms.DefaultView;private DataView AttendeeData 第28章Web服务get retum MRBData.TablesAttendees.DefaultView;private DataView EventDetailData get if(EventList!=nu
36、ll&EventList.Se1ectedValue!=null)retum new Data View(如1RBData.TablesEvents,ID=+EventList.SelectedValue.ToString(),11,Data ViewRowState.CurrentRows);else retum null;还可以删除己有的eventData宇段和EventData属性。899 大多数属性都很简单,只有最后一个属性有点新意。在本例中,要过滤Events表中的数据,只获得一个会议,用于在细节视图FormView控件中显示。注意没有使用数据源控件,所以必须自己绑定数据。为此,可调
37、用页面的DataBindO方法,但仍需要为页面上的各种数据绑定控件设置数据源DataView属性。一种较好的方式是在OnDataBindingO事件处理程序的重写版本中设置,如下所示:protected override void OnDataBinding(EventArgs e)roomList.DataSource=RoomData;attendeeList.DataSource=AttendeeData;EventList.DataSource=EventData;FormViewl.DataSource=EventDetailData;base.OnDataBinding(的;这里把
38、roomList、attendeeList、EventList和FormViewl的DataSource属性设置为前面定义的属性。接着给Page_LoadO添加DataBindO调用:void Page_Load(object sender,EventArgs e).900.第VI部分通信if(!this.IsPostBack)nameBox.Text=Context.User.Identity.Name;System.DateTime trialDate=System.DateTime.Now;calendar.SelectedDate=GetFreeDate(trialDate);Data
39、BindO;此外,还需要修改submitButton_ ClickO,以使用Web服务的AddDataO方法。其中的大部分代码保持不变,只有数据添加代码需要修改:void submitButton_Click(object sender,EventArgs e)if(Page.Is Valid)string attendees=飞foreach(ListItem attendee in attendeeList.Items)if(attendee.Selected)attendees+=attendee.Text+(+attendee.Value+),;attendees 卡and +name
40、Box.Text;try MRBService.MRBService service=new MRBService.MRBServiceO;if(service.AddEvent(eventBox.Text,int.Parse(roomList.SelectedValue),attendees,calendar.SelectedDate)1)如fRBData=nuli;DataBindO;calendar.SelectedDate=GetFreeDate(calendar.SelectedDate.AddDays(1);catch 事实上,我们所做的工作都是为了达到简化事情的目的,因此,当使用
41、设计良好的Web服第28章Web服务.901 务时,我们应更加关注用户的体验。这段代码没有很多注释。继续使用que叩Result很有帮助,对应用程序加锁也是必需的,这些内容在前面曾经提到过。最后要修改的是EventList_ SelectedlndexChangedO:void EventList_ SelectedIndexChanged(object sender,EventArgs e)FormViewl.DataSource=EventDetailData;EventList.DataSource=EventData;EventList.DataBindO;Form Viewl.Dat
42、aBindO;这就确保会议列表的数据源和细节视图正确刷新。Web站点PCSDemoSite2从外表和功能上来看与PCSDemoSite非常相似,但是PCSDemoSite2执行起来会更好一些。很容易把同-Web服务周到其他应用程序中,例如,如果原加更多的方法,就可以在Web页上显示会议,甚至可以编辑会议、参加者的名称和房间等。这样做并不会破坏PCSDemoSite2,它会忽略任何新创建的方法。但必须添加新的触发机制,以更新缓存在会议列表中的数据,因为在其他地方修改这些数据会使数据过时。28.5 使用SOAP标题交换数据本章要讨论的最后一个主题是使用SOAP标题交换信息,不包括方法参数中的信息。
43、讨论这个主题的原因是:这是一个用于维护用户注册的非常好的系统。我们将不详细论述如何设置服务器,以用于SSL连接,也不讨论可以使用IIS配置的各种身份验证方法,因为这些都不影响交换信息所需的Web服务代码。假定有个服务包含一个简单的身份验证方法,其签名如下所示:AuthenticationToken AuthenticateUser(string userName,string password);其中AuthenticationToken是我们定义的一个类型,它可以在后续方法调用中由用户使用,例如:void DoSomething(AuthenticationToken token,Other
44、ParamType param);一旦用户进行了登录,他们就可以使用从AuthenticateU serO接收到的标识(token)访问其他方法。这种技术是典型的安全Web系统,但也可以用较复杂的方式执行。使用SOAP标题交换标识(或其他数据)可以大大简化这个过程。可以对方法进行限制:要调用它们,必须在方法调用中包含指定的SOAP标题。这就简化了它们的结构,如下所示:void DoSomething(OtherParamType param);其优点是,一旦在客户机上设置了标题,它就一直存在。所以在初始设置后,就可以在后.902.第U部分通信续的所有Web方法调用中忽略身份验证标识。为了查看这
45、个过程,在C:ProCSharpChapter28目录下创建一个新的Web服务项目PCSWebService3,在App_Code目录下添加一个新类Authenti cati on T oken:using System;using System.Web.Services.Protocols;public c1ass AuthenticationToken:SoapHeader public Guid InnerToken;通常使用GUID来标识身份,因为这样可以确保它是惟一的。要声明Web服务可以有一个定制的SOAP标题,只需给服务类添加一个新类型的公共成员:public c1ass Ser
46、vice:System.Web.Services.WebService public AuthenticationToken AuthenticationTokenHeader;还需要使用System.W eb.Services.Protocols.SoapHeaderAttribute属性,使需要额外SOAP标题的Web方法正常工作。在添加这个方法前,应先添加一个非常简单的LoginO方法,客户机可以使用该方法获得身份验证标识:WebMethod public Guid Login(string userName,string password)if(userName-Karli)&(psw
47、ord-Cheese)Guid currentUser=Guid.NewGuid();ApplicationcurrentUser=currentUser;return currentUser;else ApplicationcurrentUser=Guid.Empty;return Guid.Empty;如果使用了正确的用户名和密码,就会生成一个新的Guid,它存储在会话级的变量中,并返回给用户。如果身份验证失败,就返回一个空的Guid,该Guid存储在会话层。True参数允许会话状态用于这个Web方法,因为在Web服务中,它默认为禁用,而这个功能需要它。接着是一个接收标题的方法,标题用So
48、apHeaderAttribute属性指定:WebMe伽odSoapHeaderAttribute(Authentication TokenHeader,第28章Web服务.903.Direction=SoapHeaderDirection.ln public string DoSomethingO if(ApplicationcurrentUser=!null&AuthenticationTokenHeader=!null&(Authentication TokenHeader.InnerToken 尹伯uid)SessioncurrentUser)return Authentication
49、 OK.;else return Authentication failed.;这将根据AuthenticationTokenHeader标题是否存在,是否是空的Guid,返回两个字符申中的A个(此时存在Session变量),并匹配存储在SessioncurrentUser中的一个字符串。接着创建一个简单的客户程序,测试该服务。创建一个新的Web站点PCSWebClient2,给用户界面使用F面的简单代码:fi岛ormid=fi岛orm1 runat-俨=s优erve旷r UserName:Password:asp:TextBox Runat=server ID=passwordBox份 as
50、p:Label Runat=server ID=resuItLabel份brl头 把PCSWebService3服务添加为一个Web引用(因为Web服务对于解决方案来说位于本地,所以可以单击Webservices in this solution链接,快速获得引用),名为authenticateService,再把F面的using语句添加到Default.aspx.cs中:iw e-w 。3飞EV比创阿&户iw!i m时L审时川出vdww p3a oboE nn 1I COP3 HMHM 需要使用System.Net命名空间,是因为它包含CookieContainer类。这个类用于存储Cook