Search code examples
c#wcfbasichttpbindinginstancecontextmode

Getting exceptions when InstanceContextMode is set to per session or per call


I am trying to make an application(for learning purpose) that can log in and will create an instance of "user" then save their userid in it. Then they can invoke the getUserid method and get the userid they saved. But if I use single InstanceContextMode, the userid of the old user will be replaced by a new user. So I am trying per session mode, but I am receiving exception below when I am invoking getUserid method after login.

Server stack trace: 
   At System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)
   at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at IService.getUserid()
   at ServiceClient.getUserid()

This is my codes for my service class.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class Service : IService
{
    SqlConnection con;
    SqlCommand command;
    SqlDataReader sdr;
    user loginUser;

    public Service()
    {
        dataBase();
    }

    public bool Login(string username, string password)
    {
            command.CommandText = "select userid, password from chatuser where username = '" + username + "'";
            sdr = command.ExecuteReader();
            while (sdr.Read())
            {
                if (password.Equals(sdr.GetString(1)))
                {
                    loginUser = new user(sdr.GetString(0));
                    return true;
                }
            }
            return false;
    }

    public string getUserid()
    {
        return loginUser.Userid;
    }
}

This is my user class.

[DataContract]
public class user
{
    string userid;
    public user()
    {
    }

    public user(string userid)
    {
        this.userid = userid;
    }

    [DataMember]
    public string Userid
    {
        get { return userid; }
        set { userid = value; }
    }
}

And this is my interface class.

[ServiceContract]
public interface IService
{
    [OperationContract]
     bool Login(string username, string password);

    [OperationContract]
    string getUserid();
 }

Errors occur after InstanceContextMode is changed to per session, the app runs fine when it's single but the new one will replace the old. So should it still be set to per session? Or have I done something wrong?

I am self-learning C# and new to it, so I am sorry if I am asking silly questions.


Solution

  • I am using basicHttpsBinding

    Well that's the issue since basicHttpsBinding doesn't support Session (by default) and thus if you use PerSession InstanceContextMode it's bound to throw exception since there is no session.

    You should rather be using netTcpBinding or wsHttpBinding in this case which has Session facility