locked
Urgent Help Needed regarding a Deployment Issue:SessionVariableException RRS feed

  • Question

  • Hello All

    I developed and tested a sync application in which WCF is used for transport layer.
    This was hosted on IIS 5 on windows XP on my development environment and was working fine
    On the client end it is deployed on IIS6 running on Windows Server 2003 Standard Edition SP2

    It is throwing the following exception

    Microsoft.Synchronization.Data.SessionVariableException: Unable to set session parameters in DbServerSyncProvider. Cannot obtain the value for command parameter '@sync_client_id_binary'.
       at Microsoft.Synchronization.Data.Server.DbServerSyncProvider.SetSessionParameters(IDbCommand cmd, SyncGroupMetadata groupMetadata, SyncTableMetadata tableMetadata, SyncSession syncSession, DataColumnCollection columns, SyncStage stage)
       at Microsoft.Synchronization.Data.Server.DbServerSyncProvider.EnumerateChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession, IDbTransaction transaction, EnumerateChangeType changeType)
       at Microsoft.Synchronization.Data.Server.DbServerSyncProvider.GetChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession)
       at SyncLayer.TestSyncService.GetChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession)

    The client is very concerned about security so have blocked most of the things on their network and test systems they have provided to us.
    I was wondering if this is some security issue that is strangling the WCF to set the session parameter

    Any help would be greatly appreciated
    Thanks
    • Moved by Max Wang_1983 Thursday, April 21, 2011 11:29 PM forum consolidation (From:SyncFx - Microsoft Sync Framework Database Providers [ReadOnly])
    Monday, August 3, 2009 11:44 AM

Answers

  • Hi fastian,
    Couple more followup question. Where is the SyncAgent running at (I assume the client)?
    The error means that the DbServerSyncProvider is unable to bind a value for the parameter sync_client_id_binary during the getchanges call. The runtime will usually use the SyncSession.ClientBinaryId for this parameter and the SyncSession object is usually passed by the SyncAgent. So what this means is that either you are not properly passing the SyncSession to the server or you are incorrectly using it on the server side.

    Can you post the client side proxy code for GetChanges and the server side WCF code the same function? Please remove any sensitive information such as connection strings/passwords before posting your code.

    Maheshwar Jayaraman - WCF -- http://blogs.msdn.com/dotnetremoting
    Tuesday, August 4, 2009 11:25 PM
    Moderator

All replies

  • This does not seem like a security issue to me.  Did you check the selectnewanchorcommand stored procedure?  Did it not get copied or is it possibly missing the clientidbinary input param? 
    Monday, August 3, 2009 2:49 PM
  • Thanks a lot for your reply. I see from your history of threads you were also facing some similar deployment issue in the past

    I am a novice in the internals of sync framework :(
    I have relied heavily on the approach in the article below purely using the LocalDatabaseCache wizard and its autogenerated code

    http://msdn.microsoft.com/en-us/library/cc488004.aspx

    Can you please guide me to some web resource which explains how to custom code all the autogenerated stuff.

    Following is present in the auto generated code with no use of @sync_client_id_binary
    However in all Insert,Update,Delete and SelectIncremental commands @sync_client_id_binary is being used.

    private void InitializeNewAnchorCommand() {
                // selectNewAnchorCmd command.
                this.SelectNewAnchorCommand = new System.Data.SqlClient.SqlCommand();
                this.SelectNewAnchorCommand.CommandText = "Select @sync_new_received_anchor = CHANGE_TRACKING_CURRENT_VERSION()";
                this.SelectNewAnchorCommand.CommandType = System.Data.CommandType.Text;
                System.Data.SqlClient.SqlParameter selectnewanchorcommand_sync_new_received_anchorParameter = new System.Data.SqlClient.SqlParameter("@sync_new_received_anchor", System.Data.SqlDbType.BigInt);
                selectnewanchorcommand_sync_new_received_anchorParameter.Direction = System.Data.ParameterDirection.Output;
                this.SelectNewAnchorCommand.Parameters.Add(selectnewanchorcommand_sync_new_received_anchorParameter);
            }
    Monday, August 3, 2009 7:39 PM
  • Hi,
    Can you anwer some questions for me?

    1. Which provider is hosted by the actual WCF service (server or the client)
    2. Who throws this exception, the WCF service or the proxy code?
    3. Did you modify the auto generated code in anyway?


    Maheshwar Jayaraman - WCF -- http://blogs.msdn.com/dotnetremoting
    Tuesday, August 4, 2009 5:47 AM
    Moderator
  • Hi Maheshwar

    Thank you very much for your reply
     
    I am using ALL auto generated code

    Answers to your above questions

    1. WCF is on the server and contains a Provider inherited from Microsoft.Synchronization.Data.Server.DbServerSyncProvider
    2. The following method in the wcf is throwing the exception

    public virtual SyncContext GetChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession) {
                return this._serverSyncProvider.GetChanges(groupMetadata, syncSession);
            }

    3.I didnt modify the autogenerated code in anyway. except for changing the connection string in the config file

    Lastly can you please direct me to some reference on the internals workings of Sync. Like When SyncAgent.Synchronize() is called how do they hook up to these methods of the WCF and then getting to Provider.GetChanges () what is happening

    Thanks once again for your help


    Tuesday, August 4, 2009 6:26 PM
  • For your WCF service you implemented an interface.  If you followed the SDK examples you named this interface ISyncService and defined the following operations.

    GetSchema:
    This operation simply calls each "SelectIncrementalInsertsCommand" SQL statement or stored procedure passing in parameters which would cause no data to be returned.  This command is not interested in the data, it just executes the SQL to discover what columns and data types compose the table which you specified to synch.  GetSchema is the function used when you specify on your client adapter to create a table if it does not exist.

    GetChanges:
    This method accepts input parameters which contain the tables to get changes for and the client's anchor points for those tables.  It also accepts any session paramaters for getting the changes specified by the client.  This method then returns a synccontext which most importantly contains a dataset with the records found by the server which the client needs to synchronize.

    ApplyChanges:
    Like GetChanges but backwards.  The client sends a dataset of its changes to the server.  The server then calls the InsertCommand, UpdateCommand, or DeleteCommand specified by the table adapter of the table for which the change belongs.  It is important to handle the ApplyChangeFailed event on your server adapter because the client can potentially synchronize a row in conflict with constraints on the server table; this usually results in a SQL exception.  This event provides you the opportunity to intelligently negotiate behavior when this occurs.

    I recommend attaching a debugger to your WCF service and letting the synch run if you have more questions.  You can then take a look for yourself what is contained in the objects sent to and from the service when Synchronize() is called.  Also, this might help you figure out this problem.  WCF tends to wrap or hide the actual exception with default configuration.  Another way to solve the same issue would be to define a <behaviors> tag on your wcf config.  Under this tag add the tag, 

    <

     

    serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true" />


    This will cause your WCF service to send the full stack trace to your client application.  Doing this will help you answer the question of who is really thowing the exception.  Is it the WCF method, is it the synch framework, or is it SQL Server?
    Tuesday, August 4, 2009 7:08 PM
  • Hi fastian,
    Couple more followup question. Where is the SyncAgent running at (I assume the client)?
    The error means that the DbServerSyncProvider is unable to bind a value for the parameter sync_client_id_binary during the getchanges call. The runtime will usually use the SyncSession.ClientBinaryId for this parameter and the SyncSession object is usually passed by the SyncAgent. So what this means is that either you are not properly passing the SyncSession to the server or you are incorrectly using it on the server side.

    Can you post the client side proxy code for GetChanges and the server side WCF code the same function? Please remove any sensitive information such as connection strings/passwords before posting your code.

    Maheshwar Jayaraman - WCF -- http://blogs.msdn.com/dotnetremoting
    Tuesday, August 4, 2009 11:25 PM
    Moderator
  • yes the sync agent is running on the client

    following is the proxy code on the client side

     
    /// <remarks/>
            [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/IQuestTestSyncSyncContract/GetChanges", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
            [return: System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
            public SyncContext GetChanges([System.Xml.Serialization.XmlElementAttribute(IsNullable=true)] SyncGroupMetadata groupMetadata, [System.Xml.Serialization.XmlElementAttribute(IsNullable=true)] SyncSession syncSession) {
                object[] results = this.Invoke("GetChanges", new object[] {
                            groupMetadata,
                            syncSession});
                return ((SyncContext)(results[0]));
            }


    following is the server side code for the WCF code
      ////[System.Diagnostics.DebuggerNonUserCodeAttribute()]
            public virtual SyncContext GetChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession) {
            
                return this._serverSyncProvider.GetChanges(groupMetadata, syncSession);
            }
    
    If you need more information plz let me know

    Thanks

    Tuesday, August 4, 2009 11:35 PM
  • And can you print to see what the value of SyncSession.ClientId is in the server and proxy code?

    Maheshwar Jayaraman - WCF -- http://blogs.msdn.com/dotnetremoting
    Tuesday, August 4, 2009 11:41 PM
    Moderator
  • I have exactly the same problem. You have been able to solve it?

    Regards

    Sergio
    Friday, September 11, 2009 12:53 PM
  • Hi Sergio

    It "magically" just vanished one day
    Our client has very specialized security policies and scripts with regards to windows and IIS installations which they are not willing to share with us
    So after about 10 days of total chaos in trying to solve this problem suddenly it vanished
    I seriously suspect the client changed some thing on their end coz the same code which was throwing this error magically started running
    but they are not accepting that they changed anything

    Maheshwar had been one of my point of contacts in Microsoft support sessions
    So if possible some one from Microsoft please guide us as to what specifically to check on a machine with regards to windows and iis settings so that Sync works

    Regards
    Friday, September 11, 2009 1:00 PM
  • tank's Fastian, you were my only hope, I will keep looking

    Regards

    Sergio
    Friday, September 11, 2009 1:08 PM
  • sorry for not providing any real help :(
    what i would suggest is that plz try this on some different machine and if possible one with default settings for IIS and Windows
    in my case windows was 2003 server and IIS6 which comes with lots of security settings options

    Regards
    Friday, September 11, 2009 1:55 PM