3

I have this code up on my server here (Yes I known ASMX is a bad idea but WCF doesn't work at all for some reason):

<%@ 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;
}

when I run the folloing code:

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

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

I expect to get back:

5
3

but I got back

5
5

My Solution

  1. Usee wsdl.exe to generate a proxy class
  2. Add references as needed to get it to compile
  3. Use Martin's solution

This Seems related

Edit: Added State object.

Community
  • 1
  • 1
BCS
  • 75,627
  • 68
  • 187
  • 294
  • I would strongly suggest you try to get a WCF "Hello, world" service working, then try to figure out why your WCF version of this "didn't work at all". This would be a bad reason to stick yourself with ASMX. – John Saunders Apr 30 '09 at 18:56
  • @John: WCF hello world works on my system. Trying the same code on my server fails and talks with tech support indicated that WCF is officially disallowed. – BCS Apr 30 '09 at 20:23

3 Answers3

6

Web services are stateless, so they do not store their state between multiple calls. Everytime you call a method, a new instance of the service will be created and its members will have the default values again.

What you can do, is to enable session state (as you have done) and store your state in the ASP.NET session.

Something like this:

[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"]; }

This was what is required on the server side. But you also have to take care on the client side:

Since an ASP.NET session is identified by a cookie, you have to make sure that you are passing the same cookie to the server with every web method call. To do so, you have to instantiate a CookieContainer and assign it to the web service proxy instance:

static void Main(string[] args)
{
    var ser = new ServiceReference1.TestSoapClient();
    ser.CookieContainer = new System.Net.CookieContainer();
    // ...
}
M4N
  • 94,805
  • 45
  • 217
  • 260
  • there is no CookieContainer on the type... Hmm. – BCS Apr 30 '09 at 18:01
  • 1
    this looks related :b http://webservices20.blogspot.com/2008/10/interoperability-gotcha-visual-studio.html – BCS Apr 30 '09 at 18:18
  • If you add a "Web Reference", then you should see the CookieContainer property. – M4N Apr 30 '09 at 18:28
  • trying to add a web reference just hangs at step 4 from the above blog. It just sits there forever with the "waiting" bar running. – BCS Apr 30 '09 at 18:39
  • I got around this by using WSDL.exe and adding a few System.Web.* references. – BCS Apr 30 '09 at 18:49
2

You need to turn on sessions.

[WebMethod(EnableSession = true)]
Joshua Belden
  • 10,273
  • 8
  • 40
  • 56
0

It looks to me like its not persisting class state between session method calls - probably a new object is being called each time. I'm actually not sure that you can rely on getting the same object instance each time you call the service. Joshua's answer is correct, but you'll also need to write code to persist your service's internal field into that session.

John Christensen
  • 5,020
  • 1
  • 28
  • 26