如何在WCF服务方法调用之间保留值?

时间:2015-07-21 14:10:14

标签: wcf static

我有这个WCF服务类:

public partial class OhmioSVC: IOhmioSVC_Security
{
    // Porque no funciona si la variable no es estatica?
    private static ConnectionBusiness _conn = new ConnectionBusiness();

    public ConnectionBusiness Conn
    {
        get
        {
            return _conn;
        }
    }

    public void Connect(string Usuario, string Password, string DataBase)
    {            
        Conn.ObtenerTicket (Usuario, Password, DataBase);                        
    }

    public List<Errores> GetErrors()
    {
        return Conn.MyErrors;            
    }        
}

如您所见,_conn被定义为静态,因为我需要在调用之间保留其值。如果我删除&#34;静态&#34;,并调用方法Connect(创建_conn对象)然后调用getErrores _conn变量由于某种原因是空的。

问题在于,如果我错过了呼叫&#34; connect&#34;方法我想抛出异常,但_conn仍然从最后一次调用中获取值。我知道我在这里做错了什么,但我没有看到另一种选择。任何想法?

由于

1 个答案:

答案 0 :(得分:1)

默认情况下,为每个创建的新会话实例化WCF服务类。对于一些不支持会话的绑定,然后是一个&#34; session&#34;仅跨越一个调用,这意味着对于来自客户端的两个调用(一个用于Connect,一个用于GetErrors),将创建两个OhmioSVC类的实例,这就是为什么如果您没有将ConnectionBusiness属性指定为静态,则会创建其中两个属性,您将获得所看到的结果。

您需要告诉WCF您在服务合同中要求会话。您可以通过在服务合同声明中添加SessionMode属性来实现此目的:

[ServiceContract(SessionMode = SessionMode.Required)]
public interface IOhmio_Security
{
    [OperationContract]
    void Connect(string user, string password, string db);
    [OperationContract]
    List<string> GetErrors();
}

如果你有,并且使用不支持会话的绑定(例如,BasicHttpBinding),那么你的服务将无法打开 - 然后你需要更改为支持会话的绑定(例如,WSHttpBinding)。下面的代码显示了一个有效的会话示例:

public class StackOverflow_31541498
{
    class ConnectionBusiness
    {
        List<string> errors = new List<string>();
        public void ObtenerTicket(string user, string password, string db)
        {
            errors.Add(string.Format("ObtenerTicket called: {0}, {1}, {2}", user, password, db));
        }
        public List<string> MyErrors
        {
            get
            {
                var result = new List<string>(this.errors);
                errors.Clear();
                if (result.Count == 0)
                {
                    result.Add("No errors!");
                }
                return result;
            }
        }
    }
    [ServiceContract(SessionMode = SessionMode.Required)]
    public interface IOhmio_Security
    {
        [OperationContract]
        void Connect(string user, string password, string db);
        [OperationContract]
        List<string> GetErrors();
    }
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    public class OhmioSVC : IOhmio_Security
    {
        private ConnectionBusiness _conn = new ConnectionBusiness();
        public void Connect(string user, string password, string db)
        {
            _conn.ObtenerTicket(user, password, db);
        }

        public List<string> GetErrors()
        {
            return _conn.MyErrors;
        }
    }
    static Binding GetBinding()
    {
        // var result = new BasicHttpBinding(); // This will not work, as it doesn't support sessions
        var result = new WSHttpBinding(); // This will work
        return result;
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(OhmioSVC), new Uri(baseAddress));
        host.AddServiceEndpoint(typeof(IOhmio_Security), GetBinding(), "");
        host.Open();
        Console.WriteLine("Host opened");

        var factory = new ChannelFactory<IOhmio_Security>(GetBinding(), new EndpointAddress(baseAddress));
        var proxy = factory.CreateChannel();

        proxy.Connect("user", "pwd", "db");
        var errors = proxy.GetErrors();
        Console.WriteLine("Errors:\n   {0}", string.Join("\n   ", errors));

        ((IClientChannel)proxy).Close();
        factory.Close();

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}

另一个替代方法是在您的方案中合并两种方法 - 让Connect返回错误列表,这样您就不必单独调用它们来获取它们,并且您赢了&# 39; t必须处理会议。