Domanda

Ho questo codice sul mio server qui (Sì, sapevo che ASMX è un male idea ma WCF non funziona affatto per qualche motivo):

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

quando eseguo il seguente codice:

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

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

Mi aspetto di tornare:

5
3

ma sono tornato

5
5

La mia soluzione

  1. Utilizzare wsdl.exe per generare una classe proxy
  2. Aggiungi riferimenti se necessario per farlo compilare
  3. Utilizza Soluzione di Martin

Sembra collegato

Modifica: oggetto stato aggiunto.

È stato utile?

Soluzione

I servizi Web sono apolidi, quindi non memorizzano il loro stato tra più chiamate. Ogni volta che chiami un metodo, verrà creata una nuova istanza del servizio e i suoi membri avranno nuovamente i valori predefiniti.

Quello che puoi fare è abilitare lo stato della sessione (come hai fatto) e memorizzare il tuo stato nella sessione ASP.NET.

Qualcosa del genere:

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

Questo era ciò che è richiesto sul lato server. Ma devi anche occuparti del lato client:

Poiché una sessione ASP.NET è identificata da un cookie, è necessario assicurarsi di trasmettere lo stesso cookie al server ad ogni chiamata del metodo Web. Per fare ciò, devi istanziare un CookieContainer e assegnarlo all'istanza proxy del servizio web:

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

Altri suggerimenti

Devi attivare le sessioni.

[WebMethod(EnableSession = true)]

Mi sembra che il suo stato di classe non persistente tra le chiamate del metodo di sessione - probabilmente un nuovo oggetto viene chiamato ogni volta. In realtà non sono sicuro che puoi fare affidamento su come ottenere la stessa istanza di oggetto ogni volta che chiami il servizio. La risposta di Joshua è corretta, ma dovrai anche scrivere il codice per rendere persistente il campo interno del tuo servizio in quella sessione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top