C#WebService 之Session之我见
来源:互联网 发布:php微信商城源码下载 编辑:程序博客网 时间:2024/04/28 00:25
这几天一直在学习WebService的知识。正好现在有一个项目,需要在WebService实现如下接口:
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)学习的文章: http://blog.csdn.net/wziyx513225244/article/details/6649652
- C#WebService 之Session之我见
- WebService学习之我见
- c++/cli之我见
- 【C#】c#之我见
- C++、C++学习之我见
- C++、C++学习之我见
- C++、C++学习之我见
- c语言变量之我见
- C/C++ Const之我见
- c++socket模型之我见
- C/C++位域之我见
- C语言的学习方法之我见
- C与C++区别之我见
- Spring MVC中Session的正确用法之我见
- Spring MVC中Session的正确用法之我见
- Spring MVC中Session的正确用法之我见
- Axis2 WebService之会话管理(Session)
- 软件测试之我见
- SAP 取月度期初库存和月度期末库存(历史库存)
- 标题栏的文字滚动效果
- C#——Java与C#的区别(语言级别)
- 解题笔记(32)——输入一颗二元查找树,将该树转换为它的镜像
- C# 判断系统空闲(键盘、鼠标不操作一段时间)
- C#WebService 之Session之我见
- GridView——光棒效果
- sql语句中出现笛卡尔乘积
- 【Android】HTTP协议的经典讲解
- 存储过程——分页(简单版)
- DefaultMessageListenerContainer
- Struts问题
- sendmessage发送结构体
- 早绑定和晚绑定