我的服务器上有这个代码这里(是的我知道ASMX很糟糕想法,但WCF由于某种原因根本不起作用):

<%@ WebService Language="C#" Class="Test" %>

using System.Web;
using System.Web.Services;

[WebService(Namespace = "http://smplsite.com/smplAccess")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Test : System.Web.Services.WebService
{
    State s;

    public Test()
    {
        s = (Session["foo"] ?? (Session["foo"] = new State())) as State ;
    }

    [WebMethod(EnableSession = true)]
    public void Set(int j) { i=j; }

    [WebMethod(EnableSession = true)]
    public int Get() { return i; }
}

class State
{
    public int i = 5;
}

当我运行以下代码时:

class Program
{
    static void Main(string[] args)
    {
        var ser = new ServiceReference1.TestSoapClient();

        Console.WriteLine(ser.Get());
        ser.Set(3);
        Console.WriteLine(ser.Get());
    }
}

我希望能回来:

5
3

但我回来了

5
5

我的解决方案

  1. 使用 wsdl.exe 生成代理类
  2. 根据需要添加引用以使其编译
  3. 使用 Martin's 解决方案

  4. 此看似相关

    编辑:添加了状态对象。

有帮助吗?

解决方案

Web服务是无状态的,因此它们不会在多个调用之间存储它们的状态。每次调用方法时,都会创建一个新的服务实例,其成员将再次具有默认值。

您可以做的是启用会话状态(就像您所做的那样)并将您的状态存储在ASP.NET会话中。

这样的事情:

[WebMethod(EnableSession = true)]
public void Set(int j) { Session["i"] = j; }

[WebMethod(EnableSession = true)]
public int Get() { return Session["i"] == null ? 5 : (int)Session["i"]; }

这是服务器端所需要的。但你也必须在客户方面照顾:

由于ASP.NET会话由cookie标识,因此您必须确保在每次Web方法调用时将相同的cookie传递给服务器。为此,您必须实例化CookieContainer并将其分配给Web服务代理实例:

static void Main(string[] args)
{
    var ser = new ServiceReference1.TestSoapClient();
    ser.CookieContainer = new System.Net.CookieContainer();
    // ...
}

其他提示

您需要开启会话。

[WebMethod(EnableSession = true)]

在我看来,它不像会话方法调用之间的持久类状态 - 可能每次都调用一个新对象。我实际上不确定每次调用服务时都可以依赖于获取相同的对象实例。 Joshua的回答是正确的,但您还需要编写代码以将服务的内部字段保留到该会话中。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top