我在我的服务器here上有这个代码(是的,我知道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
wsdl.exe
生成代理类编辑:添加了状态对象。
答案 0 :(得分:6)
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();
// ...
}
答案 1 :(得分:2)
您需要开启会话。
[WebMethod(EnableSession = true)]
答案 2 :(得分:0)
在我看来,它不像会话方法调用之间的持久类状态 - 可能每次都调用一个新对象。我实际上不确定每次调用服务时都可以依赖于获取相同的对象实例。 Joshua的回答是正确的,但您还需要编写代码以将服务的内部字段保留到该会话中。