Web Service 会话管理
通常通过visual studio生成的web service默认情况下是没有启用会话管理的,而且在客户端为Winforms这种类型的项目时,需要进行一些特定的处理才支持会话管理,所以为了较高的扩展性,一般不建议启用会话.如果在某些情况下要启用会话管理,该如何实现呢?
启用会话管理
[WebMethod(EnableSession=true)]
public string StateFulMetod()
就这样在WebMethod特性里给EnableSession 设为true就启用了会话管理.
由于状态的管理并不是Soap规范的一部分,之所以可以用会话状态完全得益于微软的实现是基于asp.net的.关于asp.net的会话管理,在园子里有好多文章,这里不详述.asp.net的会话是依赖于cookie的,此cookie存储一个会话id,asp.net运行时就是依据此id来与服务端的会话状态数据进行关联.由此可见在此cookie的重要性,如果 客户端根本就不支持cookie,那么即便是启用了会话管理也不会有任何效果.
如果客户端不支持cookie,那么每次客户端发出请求的时候每次都会有一个新的Session ID.下面来看看会话管理的效果.
首先建立一个服务.代码如下.
public class StatefulService : System.Web.Services.WebService
{
[WebMethod(EnableSession=true)]
public void StoreName(string name)
{
Session["Name"] = name;
}
[WebMethod(EnableSession=true)]
public string GetName()
{
if (Session["Name"] == null)
{
return "";
}
else
{
return (string)Session["Name"];
}
}
}
如果你的客户端是winform,那么就可以看到拿不到存储到会话中的信息.客户端代码如下:
private void cmdTestState_Click(object sender, System.EventArgs e)
{
// Create the proxy.
StatefulService proxy = new StatefulService();
// Set a name.
proxy.StoreName("John Smith");
// Try to retrieve the name.
MessageBox.Show("You set: " + proxy.GetName());
//此时的结果为"You set",proxy.GetName()并没有任何结果
}
如果非要在Weiform中用会话,有一个方法,那就是加一个会话容器类.并把这个容器类实例赋给proxy的CookieContainer属性即可
private System.Net.CookieContainer cookieContainer = new System.Net.CookieContainer();
proxy.CookieContainer = cookieContainer;
这样再次运行程序,会看到可以拿到会话信息.
即便你这样用了,也不保证一定可以拿到会话信息,主要是因为会话信息会超时,而这些信息是保存在服务端,客户端不可能知道会话会超时(服务端不会通知客户端,由请求响应模型决定的),所以可能会导致多次运行此方法时,得到的结果是不确定的.
个人觉得能不启用会话最好就不要启用,因为在.net情况下尚且有cookie容器可以用,那在非.net情况下,处理起来就更麻烦了.