C#WebService 之Session之我见
2011-08-29 14:58
225 查看
这几天一直在学习WebService的知识。正好现在有一个项目,需要在WebService实现如下接口:
String Login(string username, string password) // 登录方法,返回值用来指名是不是登录成功,并且这个值在之后的接口中用来找到相对应的服务器上的session。
因此WebService需要使用到Session,而网上大部分资料是说WebService是无状态的(StateLess),不怎么支持Session。因此难题出现了,首先在Web Serivice
放上声明如下Attribute,[WebMethod(EnableSession = true)],此为表示在webService上能使用Session。
现在放上我写的WebService的例子代码(service端):
客户端代码,我用的是soap方式写的,soap方式調用WebService的方法,我参看了《Programing Web Service with SOAP》。具体方式参看第三章的。我的客户端SOAP代码(我新建一个类)如下:
客户点調用代码,也就是用户端的調用代码,我写的是控制台的测试代码,如下:
写到这里进行运行,感觉一切应该按照自己想想的正确的打印出来。打印结果应该是如下这样的:
State = admin
State = Logined
结果实际运行的效果与自己设想的不太一样,实际运行的结果是
State = admin
State = admin
这样的运行结果说明,WebService 的Server端的Session,根本没有保存。通过断点调试发现,第二次读取的Session为空,就是没有保存。
因此只在Server端进行声明EnableSession = true,是不够的,这只是说明Server端现在能用session了。
经过上网查阅资料得知:要想使用Session,在进行上一步的声明之后,还要在客户端实例话WebService对象时,对其CookieContainer也要进行初始化方可使用Session的存储状态。另外在多个webservice代理中,只要含有相同的cookie,就能共用相同的session,其中的cookie通过代理类的CookieContainer.GetCookies(new Uri(s.Url))["ASP.NET_SessionId"]取得,如果其他的webserivce代理类需要用相同的session则可以用CookieContainer.Add方法,将取得的cookie加入即可(还没进行测试)。
知道了如何使用后,修改客户端的Soap代码即可,修改后的代码如下:
修改完了之后,进行测试,测试结果与设想的结果一样。
本文的一些内容出自http://63542424.blog.163.com/blog/static/18883900201161632532355/
PS:新手学习WebService的拙见,还望高手给出意见,或者推荐一些webService相关的经典书籍,小生在此不胜感激。
上面的soap端写的代码似乎还是有写问题,原因就是cookieContainer对象可能不一致,会导致服务端Session丢失。改进策略是基于单例模式的设计模式的方法进行修改的,修改的代码如下,这样就可以保证在程序中使用相同的CookieContainer进而保证Session不会意外丢失。
PS :单例模式(Singleton)学习的文章: /article/2332340.html
String Login(string username, string password) // 登录方法,返回值用来指名是不是登录成功,并且这个值在之后的接口中用来找到相对应的服务器上的session。
因此WebService需要使用到Session,而网上大部分资料是说WebService是无状态的(StateLess),不怎么支持Session。因此难题出现了,首先在Web Serivice
放上声明如下Attribute,[WebMethod(EnableSession = true)],此为表示在webService上能使用Session。
现在放上我写的WebService的例子代码(service端):
/// <summary> /// Summary description for Service1 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. [System.Web.Script.Services.ScriptService] public class Bussiness : System.Web.Services.WebService { [WebMethod(Description = "登录方法,返回值用来指名是不是登录成功,并且这个值在之后的接口中用来找到相对应的服务器上的session", EnableSession = true)] public string Login(string username, string password) { string state = ""; if (IsLogin(username)) state = "Logined"; else { state = UserHelper.Login(username, password); if (state != null && state != "Failed")// { //Session.Timeout = 1; Session[state] = username; } } return state; } [WebMethod(Description = "判断是否登录", EnableSession = true)] private bool IsLogin(string name) { if (name != null && Session[name]!=null&& Session[name].ToString() == name) return true; return false; }
客户端代码,我用的是soap方式写的,soap方式調用WebService的方法,我参看了《Programing Web Service with SOAP》。具体方式参看第三章的。我的客户端SOAP代码(我新建一个类)如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using System.Web.Services; using System.Web.Services.Protocols; using System.Xml.Serialization; namespace Test { [WebServiceBinding(Name = "BusServiceSoap", Namespace = "http://tempuri.org/")] public class BusService : SoapHttpClientProtocol { public BusService() { // this.Url = "http://localhost:4243/Bussiness.asmx"; this.Url = "http://localhost/Bussiness/Bussiness.asmx"; } [System.Web.Services.Protocols.SoapDocumentMethod( "http://tempuri.org/Login", RequestNamespace = "http://tempuri.org/", ResponseNamespace = "http://tempuri.org/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public string Login(string username, string password) { object[] result = this.Invoke("Login", new object[] { username, password }); return (string)result[0]; } } }
客户点調用代码,也就是用户端的調用代码,我写的是控制台的测试代码,如下:
namespace Test { public class Program { static void Main(string[] args) { string name = "admin"; string password = "123"; TestLogin tl = new TestLogin(name, password); string state = tl.Login(); Console.WriteLine("State = " + state); state = tl.Login(); Console.WriteLine("State = " + state); Console.Read(); } } public class TestLogin { public string name = ""; public string psw = ""; BusService bus = new BusService(); public TestLogin(string name, string psw) { this.name = name; this.psw = psw; } public string Login() { return bus.Login(this.name, this.psw); } } }
写到这里进行运行,感觉一切应该按照自己想想的正确的打印出来。打印结果应该是如下这样的:
State = admin
State = Logined
结果实际运行的效果与自己设想的不太一样,实际运行的结果是
State = admin
State = admin
这样的运行结果说明,WebService 的Server端的Session,根本没有保存。通过断点调试发现,第二次读取的Session为空,就是没有保存。
因此只在Server端进行声明EnableSession = true,是不够的,这只是说明Server端现在能用session了。
经过上网查阅资料得知:要想使用Session,在进行上一步的声明之后,还要在客户端实例话WebService对象时,对其CookieContainer也要进行初始化方可使用Session的存储状态。另外在多个webservice代理中,只要含有相同的cookie,就能共用相同的session,其中的cookie通过代理类的CookieContainer.GetCookies(new Uri(s.Url))["ASP.NET_SessionId"]取得,如果其他的webserivce代理类需要用相同的session则可以用CookieContainer.Add方法,将取得的cookie加入即可(还没进行测试)。
知道了如何使用后,修改客户端的Soap代码即可,修改后的代码如下:
[WebServiceBinding(Name = "BusServiceSoap", Namespace = "http://tempuri.org/")] public class BusService : SoapHttpClientProtocol { private static System.Net.CookieContainer cookieContainer; static BusService() { cookieContainer = new System.Net.CookieContainer(); } public BusService() { this.Url = "http://localhost:4243/Bussiness.asmx"; this.CookieContainer = new System.Net.CookieContainer(); /// this.Url = "http://localhost/Bussiness/Bussiness.asmx"; } [System.Web.Services.Protocols.SoapDocumentMethod( "http://tempuri.org/Login", RequestNamespace = "http://tempuri.org/", ResponseNamespace = "http://tempuri.org/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public string Login(string username, string password) { object[] result = this.Invoke("Login", new object[] { username, password }); return (string)result[0]; } }
修改完了之后,进行测试,测试结果与设想的结果一样。
本文的一些内容出自http://63542424.blog.163.com/blog/static/18883900201161632532355/
PS:新手学习WebService的拙见,还望高手给出意见,或者推荐一些webService相关的经典书籍,小生在此不胜感激。
上面的soap端写的代码似乎还是有写问题,原因就是cookieContainer对象可能不一致,会导致服务端Session丢失。改进策略是基于单例模式的设计模式的方法进行修改的,修改的代码如下,这样就可以保证在程序中使用相同的CookieContainer进而保证Session不会意外丢失。
namespace Test { [WebServiceBinding(Name = "BusServiceSoap", Namespace = "http://tempuri.org/")] public class BusService : SoapHttpClientProtocol { private static System.Net.CookieContainer cookieContainer; private static BusService instance; static BusService() { cookieContainer = new System.Net.CookieContainer(); instance = new BusService(); instance.CookieContainer = cookieContainer; } private BusService() { this.Url = "http://localhost:4243/Bussiness.asmx"; //this.CookieContainer = new System.Net.CookieContainer(); //this.Url = "http://localhost/Bussiness/Bussiness.asmx"; } public static BusService getInstance() { if (instance == null) instance = new BusService(); return instance; } [System.Web.Services.Protocols.SoapDocumentMethod( "http://tempuri.org/Login", RequestNamespace = "http://tempuri.org/", ResponseNamespace = "http://tempuri.org/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public string Login(string username, string password) { object[] result = this.Invoke("Login", new object[] { username, password }); return (string)result[0]; } [System.Web.Services.Protocols.SoapDocumentMethod( "http://tempuri.org/AnalyzePrescription", RequestNamespace ="http://tempuri.org/", ResponseNamespace = "http://tempuri.org/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped )] public int AnalyzePrescription(string name, List<Student> message) { object[] results = this.Invoke("AnalyzePrescription",new object[]{name,message}); return (int)results[0]; } [System.Web.Services.Protocols.SoapDocumentMethod( "http://tempuri.org/IsFinishedAnalysis", RequestNamespace = "http://tempuri.org/", ResponseNamespace = "http://tempuri.org/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped )] public bool IsFinishedAnalysis(string name, int postion) { object[] results = this.Invoke("IsFinishedAnalysis", new object[] { name, postion }); return (bool)results[0]; } [System.Web.Services.Protocols.SoapDocumentMethod( "http://tempuri.org/GetAnalyzedResult", RequestNamespace = "http://tempuri.org/", ResponseNamespace = "http://tempuri.org/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped )] public Result GetAnalyzedResult(string name, int postion) { object[] results = this.Invoke("GetAnalyzedResult", new object[] { name, postion }); return (Result)results[0]; } [System.Web.Services.Protocols.SoapDocumentMethod( "http://tempuri.org/Release", RequestNamespace = "http://tempuri.org/", ResponseNamespace = "http://tempuri.org/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped )] public bool Release(string name, int postion) { object[] results = this.Invoke("Release", new object[] { name, postion }); return (bool)results[0]; } [System.Web.Services.Protocols.SoapDocumentMethod( "http://tempuri.org/LoginOut", RequestNamespace = "http://tempuri.org/", ResponseNamespace = "http://tempuri.org/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped )] public bool LoginOut(string name) { object[] results = this.Invoke("Release", new object[] { name }); return (bool)results[0]; } } }
PS :单例模式(Singleton)学习的文章: /article/2332340.html
相关文章推荐
- C# Web Service非Soap头(Session)身份验证方法
- C#WebService下载文件
- C# ASP.NET Webservice调用外部exe无效的解决方法
- C# webservice 编写、发布、调用
- C# Barcode Generator WebService
- (转)c#.net webservice 介绍
- C#WinForm页面传值解决方法(仿web中Session)
- C# ASP.NET Webservice调用外部exe无效的解决方法
- C# WebApi 中设置Session可用
- c++ builder 和 vc调用c#.net webservice的不同
- C# webservice服务在Delphi中的调用问题
- C#WebService 调用时报 Configuration System Failed to Initialize 或者 配置初始化失败
- 万能的Java WebService调用程序支持C# JAVA WS调用
- C#—WebService
- c# webservice上传下载
- C# webservice简单例子
- C# WebService首次调用慢
- .net C# WebService 开发(获取数据库数据)
- c# Webservice 生成代理类并在客户端调用
- Deploy your web service written with C#