locked
WCF Sync on Desktop to create SDF RRS feed

  • Question

  • Hello,

    I have created a windows desktop application that user would use to create SDF using Sync Services (WCF based). I followed the sample on http://blogs.msdn.com/sync/archive/2008/07/14/using-wcf-for-communcation-in-a-mobile-sync-application.aspx

    to design the sync service. I then used svcutil.exe to generate proxies. I also modified the proxy for the GetSchema method to following:

    public SyncSchema GetSchema(string[] tableNames, SyncSession syncSession)
        {
            return base.Channel.GetSchema(tableNames, syncSession);
        }

    so that the method accepts array instead of collection for tableNames. However I am still getting following error:

    "Object of type 'System.String[]' cannot be converted to type 'System.Collections.ObjectModel.Collection`1[System.String]'."


    "   at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)\r\n   at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)\r\n   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)\r\n   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)\r\n   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)\r\n   at Microsoft.Synchronization.Data.ServerSyncProviderProxy.GetSchema(Collection`1 tableNames, SyncSession syncSession)\r\n   at Microsoft.Synchronization.SyncAgent.InitClientSchema()\r\n   at Microsoft.Synchronization.SyncAgent.Synchronize()\r\n   at Timmons.VectorControl.Mobile.SDFCreator.SDFCreatorForm.SynchronizeTables() in C:\\Projects\\Newport_News_Mobile\\src\\Timmons.VectorControl.Mobile\\Timmons.VectorControl.Mobile.SDFCreator\\SDFCreatorForm.cs:line 255"

    Here is my Iservice code

    public interface ISyncService
        {
            [OperationContract]
            string GetData(int value);
            [OperationContract]
            CompositeType GetDataUsingDataContract(CompositeType composite);
            #region sync service Server provider abstract methods
            [OperationContract]
            SyncServerInfo GetServerInfo(SyncSession syncSession);
            [OperationContract]
            SyncContext ApplyChanges(Microsoft.Synchronization.Data.SyncGroupMetadata groupMetadata, DataSet dataSet, SyncSession syncSession);
            [OperationContract]
            SyncContext GetChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession);
            [OperationContract]
            SyncSchema GetSchema(string[] tableNames, SyncSession syncSession);
            #endregion
        }
        [DataContract]
        public class CompositeType
        {
            bool boolValue = true;
            string stringValue = "Hello ";
            [DataMember]
            public bool BoolValue { get { return boolValue; } set { boolValue = value; } }
            [DataMember]
            public string StringValue { get { return stringValue; } set { stringValue = value; } }
        }


    I also tried to create SDF from Mobile app but keep getting same argument exception. Here is the code for the Service.cs

    private void CreateServerProvider()
            {
                SqlConnection serverConnection;
                SqlSyncAdapterBuilder builder;

                //serverConnection = new SqlConnection(_connString);
                serverConnection = new SqlConnection(string.Format("server = {0}; database = {1}; integrated security = true", _server, _db));
                serverConnection.Open();
                _serverSyncProvider = new DbServerSyncProvider();
                _serverSyncProvider.Connection = serverConnection;
              
                #region Download Only Sync
                SyncAdapter adaptorWorkOrder = new SyncAdapter(_tableOwner + TableWorkOrder);

                #region Inserts
                SqlCommand incInsWorkOrderCmd = new SqlCommand();
                incInsWorkOrderCmd.CommandType = CommandType.StoredProcedure;
                incInsWorkOrderCmd.CommandText = _tableOwner + SPWorkOrderIncrementalInsert;
                incInsWorkOrderCmd.Parameters.Add("@" + SyncSession.SyncLastReceivedAnchor, SqlDbType.Binary, 8);
                incInsWorkOrderCmd.Parameters.Add("@" + SyncSession.SyncNewReceivedAnchor, SqlDbType.Binary, 8);

                adaptorWorkOrder.SelectIncrementalInsertsCommand = incInsWorkOrderCmd;
                #endregion

                #region Updates
                SqlCommand incUpdWorkOrderCmd = new SqlCommand();
                incUpdWorkOrderCmd.CommandType = CommandType.StoredProcedure;
                incUpdWorkOrderCmd.CommandText = _tableOwner + SPWorkOrderIncrementalUpdate;
                incUpdWorkOrderCmd.Parameters.Add("@" + SyncSession.SyncLastReceivedAnchor, SqlDbType.Binary, 8);
                incUpdWorkOrderCmd.Parameters.Add("@" + SyncSession.SyncNewReceivedAnchor, SqlDbType.Binary, 8);

                adaptorWorkOrder.SelectIncrementalUpdatesCommand = incUpdWorkOrderCmd;
                #endregion

                #region Deletes
                SqlCommand incDelTimeCodesCmd = new SqlCommand();
                incDelTimeCodesCmd.CommandType = CommandType.StoredProcedure;
                incDelTimeCodesCmd.CommandText = _tableOwner + SPWorkOrderIncrementalDelete;
                incDelTimeCodesCmd.Parameters.Add("@" + SyncSession.SyncLastReceivedAnchor, SqlDbType.Binary, 8);
                incDelTimeCodesCmd.Parameters.Add("@" + SyncSession.SyncNewReceivedAnchor, SqlDbType.Binary, 8);

                adaptorWorkOrder.SelectIncrementalDeletesCommand = incDelTimeCodesCmd;
                #endregion

                _serverSyncProvider.SyncAdapters.Add(adaptorWorkOrder);

                #endregion

                SqlCommand anchorCmd = new SqlCommand();
                anchorCmd.CommandType = CommandType.Text;
                anchorCmd.CommandText = "Select @" + SyncSession.SyncNewReceivedAnchor + " = min_active_rowversion() - 1";
                //anchorCmd.CommandText = "Select @" + SyncSession.SyncNewReceivedAnchor + " = @@DBTS";  // for SQL Server 2005 SP2, use "min_active_rowversion() - 1"

                anchorCmd.Parameters.Add("@" + SyncSession.SyncNewReceivedAnchor, SqlDbType.Timestamp).Direction = ParameterDirection.Output;
                _serverSyncProvider.SelectNewAnchorCommand = anchorCmd;

    Any help is highly appreciated.

    Thanks
    • Moved by Max Wang_1983 Thursday, April 21, 2011 11:21 PM forum consolidation (From:SyncFx - Microsoft Sync Framework Database Providers [ReadOnly])
    Tuesday, September 15, 2009 9:02 PM

Answers

All replies

  • Hello,

    I have created a windows desktop application that user would use to create SDF using Sync Services (WCF based). I followed the sample on http://blogs.msdn.com/sync/archive/2008/07/14/using-wcf-for-communcation-in-a-mobile-sync-application.aspx

    to design the sync service. I then used svcutil.exe to generate proxies. I also modified the proxy for the GetSchema method to following:

    public SyncSchema GetSchema(string[] tableNames, SyncSession syncSession)
        {
            return base.Channel.GetSchema(tableNames, syncSession);
        }

    so that the method accepts array instead of collection for tableNames. However I am still getting following error:

    "Object of type 'System.String[]' cannot be converted to type 'System.Collections.ObjectModel.Collection`1[System.String]'."


    "   at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)\r\n   at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)\r\n   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)\r\n   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)\r\n   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)\r\n   at Microsoft.Synchronization.Data.ServerSyncProviderProxy.GetSchema(Collection`1 tableNames, SyncSession syncSession)\r\n   at Microsoft.Synchronization.SyncAgent.InitClientSchema()\r\n   at Microsoft.Synchronization.SyncAgent.Synchronize()\r\n   at Timmons.VectorControl.Mobile.SDFCreator.SDFCreatorForm.SynchronizeTables() in C:\\Projects\\Newport_News_Mobile\\src\\Timmons.VectorControl.Mobile\\Timmons.VectorControl.Mobile.SDFCreator\\SDFCreatorForm.cs:line 255"

    Here is my Iservice code

    public interface ISyncService
        {
            [OperationContract]
            string GetData(int value);
            [OperationContract]
            CompositeType GetDataUsingDataContract(CompositeType composite);
            #region sync service Server provider abstract methods
            [OperationContract]
            SyncServerInfo GetServerInfo(SyncSession syncSession);
            [OperationContract]
            SyncContext ApplyChanges(Microsoft.Synchronization.Data.SyncGroupMetadata groupMetadata, DataSet dataSet, SyncSession syncSession);
            [OperationContract]
            SyncContext GetChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession);
            [OperationContract]
            SyncSchema GetSchema(string[] tableNames, SyncSession syncSession);
            #endregion
        }
        [DataContract]
        public class CompositeType
        {
            bool boolValue = true;
            string stringValue = "Hello ";
            [DataMember]
            public bool BoolValue { get { return boolValue; } set { boolValue = value; } }
            [DataMember]
            public string StringValue { get { return stringValue; } set { stringValue = value; } }
        }

    Any help is highly appreciated.

    Thanks
    • Merged by Riquel_Dong Wednesday, September 23, 2009 8:50 AM the same issue
    Tuesday, September 15, 2009 7:24 PM
  • Remove this switch when you generate proxy with svcutil.exe: /ct:System.Collections.Generic.List`1
    Then you needn't to change the signature of GetSchema.

    I recommend to added service reference in Visual Studio with Collection type as System.Array. svcutil.exe will genrate the types in SynFx for you.
    Tuesday, September 15, 2009 11:40 PM
  • Thanks Bob. I added service reference with collection type as system.array but still got the same error.
    Wednesday, September 16, 2009 1:42 PM
  • Any other ideas? I will probably to go back to creating a SOAP Sync Service to make it work.
    Wednesday, September 16, 2009 6:41 PM
  • [OperationContract]
            SyncSchema GetSchema(string[] tableNames, SyncSession syncSession);

    this signature should be change to:

    [OperationContract()]
            SyncSchema GetSchema(Collection<string> tableNames, SyncSession syncSession);
    Wednesday, September 16, 2009 11:40 PM
  • Hi Tek,

    Please let me know the following information:

    1. where you receive the errors. Is it the service end or client end?

    2. How do you modify the code to the proxy class?

    Whether you can fix this issue by this thread:
    http://social.microsoft.com/Forums/en-US/uklaunch2007ado.net/thread/f00d5c5d-6654-4a84-ac02-684b85eb1ec3

     
    Best regards,
    Riquel
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Monday, September 21, 2009 5:18 AM