在WebService中使用Session的问题 http://www.x2blog.cn/BoyTNT/?tid=6599

来源:互联网 发布:python教程推荐 编辑:程序博客网 时间:2024/05/21 10:32
[系统环境]
    ASP.Net 1.1 环境, 站点A运行WebService,站点B通过本地代理类调用A的服务,两者位于同一台服务器上,只不过是独立的两个WebApplication。

[问题描述]
    出于安全性考虑,设计了如下的服务请求流程:
    B向A发送密码登录 → A检查密码并置Session → B请求A的服务 → A检查Session后处理请求

    实际测试中发现A置Session成功,但B向A请求服务时,Session检查失败。

[解决过程]
    首先检查“[WebMethod(EnableSession=true)]”标记,发现都写了,看来问题不是出在这里。
    然后是在Visual Studio中跟踪,在B端下断点F11,可以看到A端的WebService中置Session成功,但处理请求之前的检查时Session又为null了。
    使用IE直接测试,用同一浏览器先向A发送密码登录,然后调用A的服务,这回成功了,看来问题出在调用环节上。

    回来考虑Session的实现原理,服务端能识别出客户端,是靠将一个唯一ID串发给客户端,客户端下次请求时还使用这个ID,服务端就可以识别出它了。
    基于上面的测试,IE可以而代码不行,猜测有可能是接收或发送这个ID串的环节出现了问题。
    代理类是从System.Web.Services.Protocols.SoapHttpClientProtocol派生的,于是在MSDN上查了一下相关属性和方法,与Cookie相关的有一个属性:

public CookieContainer CookieContainer {get; set;}

属性值
    CookieContainer,它表示 Web 服务客户端的 Cookie。

备注
    如果 XML Web services 方法使用会话状态,则将在响应标头中将一个为 XML Web services 客户端唯一标识会话的 Cookie 传递回该 XML Web services 客户端。为了使 XML Web services 维护客户端的会话状态,客户端必须保持 Cookie。客户端可以通过在调用 XML Web services 之前创建 CookieContainer 的新实例并将其分配给代理类的 CookieContainer 属性来接收 HTTP Cookie。若需在代理类实例超出范围时维护会话状态,客户端必须在 XML Web services 调用之间保持 HTTP Cookie。例如,Web 窗体客户端可以通过在自己的会话状态中保存 CookieContainer 来保持 HTTP Cookie。因为并非所有 XML Web services 都使用会话状态,因而并不总是要求客户端使用客户端代理的 CookieContainer 属性,所以 XML Web services 文档应该说明是否使用会话状态。

    这下看得很明白了,就是因为没有置这个CookieContainer,导致A返回的Cookie信息没有记录下来,第二次请求时不使用此Cookie值,就造成了A无法识别B。解决方法也就出来了,由于我需要一次登录多次调用,所以生成一个全局静态的CookieContainer对象供各个代理类调用就可以了,再次测试通过。