我有这个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仍然从最后一次调用中获取值。我知道我在这里做错了什么,但我没有看到另一种选择。任何想法?
由于
答案 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必须处理会议。