在WebService中我们常常需要管理程序状态,如用户登录状态、权限状态等。同Web程序一样,我们可以使用Session,Application 来管理WebService的状态。
默认情况下,.Net的WebService是无状态的,其实要想使WebService获得状态管理的功能也很简单,那就是把WebMethod的属性EnableSession 设为true即可,如下例:
public class UserSystem : System.Web.Services.WebService
{
[WebMethod( EnableSession=true)]
public int CheckLogin(String UserName,String Password)
{
if(CheckValid(UserName,Password))
{
Session["username"]=UserName;
return 1;
}
else
{
Session["username"]="";
return 0;
}
}
[WebMethod(true)] //跟EnableSession=true效果一样
public String GetUserName()
{
//String UserName;
if(Session["username"]!=null&& Session["username"]!="")
{
return(String)Session["username"];
}
else
return "";
}
}
}
上面我们在UserSystem这个WebService中建了两个Webmethod,一个用来判断登陆,如果登陆成功则设置Session[“username”]为登陆的用户名,另外一个作为试验获取登陆的用户名。
要使Web services 维护客户端的会话状态,无论是web客户端还是桌面程序客户端都必须保持 Cookie。客户端可以通过在调用XML Web services 之前创建 CookieContainer 的新实例并将其分配给代理类的CookieContainer 属性来接收 HTTP Cookie。
客户端的调用方法:
UserSystem userSystem=new UserSystem();
userSystem. CookieContainer =new CookieContainer();
//下面两行用来测试,看看UserName能不能保持
userSystem .CheckLogin("WangErxiao","111111");
String UserName=userSystem.GetUserName();
如果在一个项目中使用了不止一个WebService 或者UserSystem在不同的地方被实例化了多次,怎么样让所有的Web Service状态保持一致呢?
就像下面,如果有另外一个Web Service ,里面有个WebMethod 需要确定用户的权限,当然这就需要先取出用户名,怎么样得到上面的UserSystem存进去的用户名呢?
public class SupportSystem : System.Web.Services.WebService
{
[WebMethod(true)]
public int CheckRight(int RightID)
{
String UserName;
if(Session["username"]!=null&& Session["username"]!="")
{
UserName=(String)Session["username"];
//根据UserName 和RightID 来判断有没有权限
}
return 0;
}
}
}
我们如果象下面这样做
SupportSystem supportSystem=new SupportSystem ();
supportSystem. CookieContainer =new CookieContainer();
supportSystem.CheckRight(1);
跟踪CheckRight的代码,你会发现 Session["username"]并没有被保持下来,问题就出在这个new CookieContainer()上面。若需在代理类实例超出范围时维护会话状态,客户端必须在 XML
Web services 调用之间保持 HTTP Cookie。至于怎么样在Web services 调用之间保持 HTTP Cookie,我们可以使用静态成员,比如定义一个类似下面的类
public class GlobalSettings
{
private static CookieContainer _commonCookieContainer=new CookieContainer();
private GlobalSettings()
{
}
public static CookieContainer CommonCookieContainer
{
get
{
return _commonCookieContainer;
}
}
}
在实例化Web Service 代理类的时候,使其实例化类的CookieContainer成员等于这个CommonCookieContainer 就可以了
如
UserSystem userSystem=new UserSystem();
userSystem. CookieContainer = GlobalSettings. CommonCookieContainer;
SupportSystem supportSystem=new SupportSystem ();
supportSystem. CookieContainer = GlobalSettings. CommonCookieContainer;
这样一来userSystem和supportSystem中的session 就可以保持一致了,这时候运行supportSystem.CheckRight(1);就可以看到其中可以使用Session["username"]取到 userSystem .CheckLogin()中存入的值了。