Example #1
0
 protected virtual void OnApplyChangeFailed(ApplyChangeFailedEventArgs args)
 {
     if (ApplyChangeFailed != null)
     {
         ApplyChangeFailed(this, args);
     }
 }
Example #2
0
        static void ApplyChangedFailed(object sender, ApplyChangeFailedEventArgs e)
        {
            e.Action = ApplyAction.Continue;
            return;

            // tables name
            string serverTableName = e.Conflict.RemoteChanges.TableName;
            string clientTableName = e.Conflict.LocalChanges.TableName;

            // server row in conflict
            var dmRowServer = e.Conflict.RemoteChanges.Rows[0];
            var dmRowClient = e.Conflict.LocalChanges.Rows[0];

            // Example 1 : Resolution based on rows values
            if ((int)dmRowServer["ClientID"] == 100 && (int)dmRowClient["ClientId"] == 0)
            {
                e.Action = ApplyAction.Continue;
            }
            else
            {
                e.Action = ApplyAction.RetryWithForceWrite;
            }

            // Example 2 : resolution based on conflict type
            // Line exist on client, not on server, force to create it
            //if (e.Conflict.Type == ConflictType.RemoteInsertLocalNoRow || e.Conflict.Type == ConflictType.RemoteUpdateLocalNoRow)
            //    e.Action = ApplyAction.RetryWithForceWrite;
            //else
            //    e.Action = ApplyAction.RetryWithForceWrite;
        }
Example #3
0
    static void SqlSyncProvider_ApplyChangedFailed(object sender, ApplyChangeFailedEventArgs e)
    {
        // Note: LocalChange table name may be null if the record does not exist on the server. So use the remote table name.
        string tableName = e.Conflict.RemoteChange.TableName;

        // Line exist on client, not on server, force to create it
        if (e.Conflict.Type == ConflictType.LocalNoRowRemoteUpdate)
        {
            e.Action = ApplyAction.Rollback;
        }
        else
        {
            e.Action = ApplyAction.Continue;
        }
    }
Example #4
0
        //<snippetOCS_CS_Conflicts_ClientApplyChangeFailed>
        private void SampleClientSyncProvider_ApplyChangeFailed(object sender, ApplyChangeFailedEventArgs e)
        {
            //Log event data from the client side.
            EventLogger.LogEvents(sender, e);

            //Force write any inserted server rows that are in conflict
            //when they are downloaded.
            if (e.Conflict.ConflictType == ConflictType.ClientInsertServerInsert)
            {
                e.Action = ApplyAction.RetryWithForceWrite;
            }

            if (e.Conflict.ConflictType == ConflictType.ClientUpdateServerUpdate)
            {
                //Logic goes here.
            }

            if (e.Conflict.ConflictType == ConflictType.ErrorsOccurred)
            {
                //Logic goes here.
            }
        }
Example #5
0
        private void SampleServerSyncProvider_ApplyChangeFailed(object sender, ApplyChangeFailedEventArgs e)
        {
            //Verbose tracing includes information about conflicts. In this application,
            //Verbose tracing is disabled, and we have decided to flag conflicts with a
            //warning.
            //Check if Verbose tracing is enabled and if the conflict is an error.
            //If the conflict is not an error, we write a warning to the trace file
            //with information about the conflict.
            //<snippetOCS_CS_Tracing_ApplyChangeFailed>
            if (SyncTracer.IsVerboseEnabled() == false && e.Conflict.ConflictType != ConflictType.ErrorsOccurred)
            {
                DataTable     conflictingServerChange = e.Conflict.ServerChange;
                DataTable     conflictingClientChange = e.Conflict.ClientChange;
                int           serverColumnCount       = conflictingServerChange.Columns.Count;
                int           clientColumnCount       = conflictingClientChange.Columns.Count;
                StringBuilder clientRowAsString       = new StringBuilder();
                StringBuilder serverRowAsString       = new StringBuilder();

                for (int i = 0; i < clientColumnCount; i++)
                {
                    clientRowAsString.Append(conflictingClientChange.Rows[0][i] + " | ");
                }

                for (int i = 0; i < serverColumnCount; i++)
                {
                    serverRowAsString.Append(conflictingServerChange.Rows[0][i] + " | ");
                }

                SyncTracer.Warning(1, "CONFLICT DETECTED FOR CLIENT {0}", e.Session.ClientId);
                SyncTracer.Warning(2, "** Client change **");
                SyncTracer.Warning(2, clientRowAsString.ToString());
                SyncTracer.Warning(2, "** Server change **");
                SyncTracer.Warning(2, serverRowAsString.ToString());
            }
            //</snippetOCS_CS_Tracing_ApplyChangeFailed>
        }
Example #6
0
        //Create client and server log files, and write to them
        //based on data from the ApplyChangeFailedEventArgs.
        public static void LogEvents(object sender, ApplyChangeFailedEventArgs e)
        {
            string logFile = String.Empty;
            string site    = String.Empty;

            if (sender is SampleServerSyncProvider)
            {
                logFile = "ServerLogFile.txt";
                site    = "server";
            }
            else if (sender is SampleClientSyncProvider)
            {
                logFile = "ClientLogFile.txt";
                site    = "client";
            }

            StreamWriter  streamWriter = File.AppendText(logFile);
            StringBuilder outputText   = new StringBuilder();

            outputText.AppendLine("** CONFLICTING CHANGE OR ERROR AT " + site.ToUpper() + " **");
            outputText.AppendLine("Table for which error or conflict occurred: " + e.TableMetadata.TableName);
            outputText.AppendLine("Sync stage: " + e.Conflict.SyncStage);
            outputText.AppendLine("Conflict type: " + e.Conflict.ConflictType);

            //If it is a data conflict instead of an error, print out
            //the values of the rows at the client and server.
            if (e.Conflict.ConflictType != ConflictType.ErrorsOccurred &&
                e.Conflict.ConflictType != ConflictType.Unknown)
            {
                DataTable serverChange  = e.Conflict.ServerChange;
                DataTable clientChange  = e.Conflict.ClientChange;
                int       serverRows    = serverChange.Rows.Count;
                int       clientRows    = clientChange.Rows.Count;
                int       serverColumns = serverChange.Columns.Count;
                int       clientColumns = clientChange.Columns.Count;

                for (int i = 0; i < serverRows; i++)
                {
                    outputText.Append("Server row: ");

                    for (int j = 0; j < serverColumns; j++)
                    {
                        outputText.Append(serverChange.Rows[i][j] + " | ");
                    }

                    outputText.AppendLine(String.Empty);
                }

                for (int i = 0; i < clientRows; i++)
                {
                    outputText.Append("Client row: ");

                    for (int j = 0; j < clientColumns; j++)
                    {
                        outputText.Append(clientChange.Rows[i][j] + " | ");
                    }

                    outputText.AppendLine(String.Empty);
                }
            }

            if (e.Conflict.ConflictType == ConflictType.ErrorsOccurred)
            {
                outputText.AppendLine("Error message: " + e.Error.Message);
            }

            streamWriter.WriteLine(DateTime.Now.ToShortTimeString() + " | " + outputText.ToString());
            streamWriter.Flush();
            streamWriter.Dispose();
        }
Example #7
0
        private void SampleServerSyncProvider_ApplyChangeFailed(object sender, ApplyChangeFailedEventArgs e)
        {
            //Log information for the ApplyChangeFailed event.
            EventLogger.LogEvents(sender, e);

            //Respond to four different types of conflicts:
            // * ClientDeleteServerUpdate
            // * ClientUpdateServerDelete
            // * ClientInsertServerInsert
            // * ClientUpdateServerUpdate
            //
            if (e.Conflict.ConflictType == ConflictType.ClientDeleteServerUpdate)
            {
                //With the commands we are using, the default is for the server
                //change to win and be applied to the client. Here, we accept the
                //default on the server side. We also set ConflictResolver.ServerWins
                //for this conflict in the client provider. This ensures that the server
                //change is applied to the client during the download phase.
                Console.WriteLine(String.Empty);
                Console.WriteLine("***********************************");
                Console.WriteLine("A client delete / server update conflict was detected.");

                e.Action = ApplyAction.Continue;

                Console.WriteLine("The server change will be applied at the client.");
                Console.WriteLine("***********************************");
                Console.WriteLine(String.Empty);
            }

            //<snippetOCS_CS_Conflicts_ServerApplyChangeFailed>
            if (e.Conflict.ConflictType == ConflictType.ClientUpdateServerDelete)
            {
                //For client-update/server-delete conflicts, we force the client
                //change to be applied at the server. The stored procedure specified for
                //customerSyncAdapter.UpdateCommand accepts the @sync_force_write parameter
                //and includes logic to handle this case.
                Console.WriteLine(String.Empty);
                Console.WriteLine("***********************************");
                Console.WriteLine("A client update / server delete conflict was detected.");

                e.Action = ApplyAction.RetryWithForceWrite;

                Console.WriteLine("The client change was retried at the server with RetryWithForceWrite.");
                Console.WriteLine("***********************************");
                Console.WriteLine(String.Empty);
            }
            //</snippetOCS_CS_Conflicts_ServerApplyChangeFailed>

            if (e.Conflict.ConflictType == ConflictType.ClientInsertServerInsert)
            {
                //Similar to how we handled the client-delete/server-update conflict.
                //In this case, we set ConflictResolver.FireEvent and use RetryWithForceWrite
                //for this conflict in the client provider. This is equivalent to
                //ConflictResolver.ServerWins, and ensures that the server
                //change is applied to the client during the download phase.
                Console.WriteLine(String.Empty);
                Console.WriteLine("***********************************");
                Console.WriteLine("A client insert / server insert conflict was detected.");

                e.Action = ApplyAction.Continue;

                Console.WriteLine("The server change will be applied at the client.");
                Console.WriteLine("***********************************");
                Console.WriteLine(String.Empty);
            }

            if (e.Conflict.ConflictType == ConflictType.ClientUpdateServerUpdate)
            {
                //For client-update/server-update conflicts, we want to
                //allow the user to specify the conflict resolution option.
                //
                //It is possible for the Conflict object from the
                //server to have more than one row. Because our custom
                //resolution code only works with one row at a time,
                //we only allow the user to select a resolution
                //option if the object contains a single row.
                if (e.Conflict.ServerChange.Rows.Count > 1)
                {
                    Console.WriteLine(String.Empty);
                    Console.WriteLine("***********************************");
                    Console.WriteLine("A client update / server update conflict was detected.");

                    e.Action = ApplyAction.Continue;

                    Console.WriteLine("The server change will be applied at the client.");
                    Console.WriteLine("***********************************");
                    Console.WriteLine(String.Empty);
                }
                else
                {
                    Console.WriteLine(String.Empty);
                    Console.WriteLine("***********************************");
                    Console.WriteLine("A client update / server update conflict was detected.");
                    Console.WriteLine("Conflicting rows are displayed below.");
                    Console.WriteLine("***********************************");

                    //Get the conflicting changes from the Conflict object
                    //and display them. The Conflict object holds a copy
                    //of the changes; updates to this object will not be
                    //applied. To make changes, use the Context object,
                    //which is demonstrated in the next section of code
                    //under ' case "CU" '.
                    DataTable conflictingServerChange = e.Conflict.ServerChange;
                    DataTable conflictingClientChange = e.Conflict.ClientChange;
                    int       serverColumnCount       = conflictingServerChange.Columns.Count;
                    int       clientColumnCount       = conflictingClientChange.Columns.Count;

                    Console.WriteLine(String.Empty);
                    Console.WriteLine("Server row: ");
                    Console.Write(" | ");

                    //Display the server row.
                    for (int i = 0; i < serverColumnCount; i++)
                    {
                        Console.Write(conflictingServerChange.Rows[0][i] + " | ");
                    }

                    Console.WriteLine(String.Empty);
                    Console.WriteLine(String.Empty);
                    Console.WriteLine("Client row: ");
                    Console.Write(" | ");

                    //Display the client row.
                    for (int i = 0; i < clientColumnCount; i++)
                    {
                        Console.Write(conflictingClientChange.Rows[0][i] + " | ");
                    }

                    Console.WriteLine(String.Empty);
                    Console.WriteLine(String.Empty);

                    //Ask for a conflict resolution option.
                    Console.WriteLine("Enter a resolution option for this conflict:");
                    Console.WriteLine("SE = server change wins");
                    Console.WriteLine("CL = client change wins");
                    Console.WriteLine("CU = custom resolution (combine rows)");

                    string conflictResolution = Console.ReadLine();
                    conflictResolution.ToUpper();

                    switch (conflictResolution)
                    {
                    case "SE":

                        //Again, this this is the default for the commands we are using:
                        //the server change is persisted and then downloaded to the client.
                        e.Action = ApplyAction.Continue;
                        Console.WriteLine(String.Empty);
                        Console.WriteLine("The server change will be applied at the client.");

                        break;

                    case "CL":

                        //Override the default by specifying that the client row
                        //should be applied at the server. The stored procedure specified
                        //for customerSyncAdapter.UpdateCommand accepts the @sync_force_write
                        //parameter and includes logic to handle this case.
                        e.Action = ApplyAction.RetryWithForceWrite;
                        Console.WriteLine(String.Empty);
                        Console.WriteLine("The client change was retried at the server with RetryWithForceWrite.");

                        break;

                    case "CU":

                        //Provide a custom resolution scheme that takes each conflicting
                        //column and applies the combined contents of the column to the
                        //client and server. This is not necessarily a resolution scheme
                        //that you would use in production. Instead, it is used to
                        //demonstrate the various ways you can interact with conflicting
                        //data during synchronization.
                        //
                        //Get the ID for the conflicting row from the client data table,
                        //and add it to a list of GUIDs. We update rows at the server
                        //based on this list.
                        Guid customerId = (Guid)conflictingClientChange.Rows[0]["CustomerId"];
                        _updateConflictGuids.Add(customerId);

                        //Create a dictionary to hold the column ordinal and value for
                        //any columns that are in confict.
                        Dictionary <int, string> conflictingColumns = new Dictionary <int, string>();
                        string combinedColumnValue;

                        //Determine which columns are different at the client and server.
                        //We already looped through these columns once, but we wanted to
                        //keep this code separate from the display code above.
                        for (int i = 0; i < clientColumnCount; i++)
                        {
                            if (conflictingClientChange.Rows[0][i].ToString() != conflictingServerChange.Rows[0][i].ToString())
                            {
                                //If we find a column that is different, combine the values from
                                //the client and server, and write "| conflict |" between them.
                                combinedColumnValue = conflictingClientChange.Rows[0][i] + "  | conflict |  " +
                                                      conflictingServerChange.Rows[0][i];
                                conflictingColumns.Add(i, combinedColumnValue);
                            }
                        }

                        //Loop through the rows in the Context object, which exposes
                        //the set of changes that are uploaded from the client.
                        //Note: In the ApplyChangeFailed event for the client provider,
                        //you have access to the set of changes that was downloaded from
                        //the server.
                        DataTable allClientChanges     = e.Context.DataSet.Tables["Customer"];
                        int       allClientRowCount    = allClientChanges.Rows.Count;
                        int       allClientColumnCount = allClientChanges.Columns.Count;

                        for (int i = 0; i < allClientRowCount; i++)
                        {
                            //Find the changed row with the GUID from the Conflict object.
                            if (allClientChanges.Rows[i].RowState == DataRowState.Modified &&
                                (Guid)allClientChanges.Rows[i]["CustomerId"] == customerId)
                            {
                                //Loop through the columns and check whether the column
                                //is in the conflictingColumns dictionary. If it is,
                                //update the value in the allClientChanges Context object.
                                for (int j = 0; j < allClientColumnCount; j++)
                                {
                                    if (conflictingColumns.ContainsKey(j))
                                    {
                                        allClientChanges.Rows[i][j] = conflictingColumns[j];
                                    }
                                }
                            }
                        }

                        //Apply the changed row with its combined values to the server.
                        //This change will persist at the server, but it will not be
                        //downloaded with the SelectIncrementalUpdate command that we use.
                        //It will not download the change because it checks for the UpdateId,
                        //which is still set to the client that made the upload.
                        //We use the ChangesApplied event to set the UpdateId for the
                        //change to a value that represents the server. This ensures
                        //that the change is applied at the client during the download
                        //phase of synchronization (see SampleServerSyncProvider_ChangesApplied).
                        e.Action = ApplyAction.RetryWithForceWrite;

                        Console.WriteLine(String.Empty);
                        Console.WriteLine("The custom change was retried at the server with RetryWithForceWrite.");

                        break;

                    default:
                        Console.WriteLine(String.Empty);
                        Console.WriteLine("Not a valid resolution option.");

                        break;
                    }
                }

                Console.WriteLine(String.Empty);
            }
        }
Example #8
0
 void SampleClientSyncProvider_ApplyChangeFailed(object sender, ApplyChangeFailedEventArgs e)
 {
     Console.Write("APPLYING CHANGES FAILED..");
 }
Example #9
0
 protected override void OnApplyChangeFailed(ApplyChangeFailedEventArgs value)
 {
     Console.Write("applying changes failed..");
     base.OnApplyChangeFailed(value);
 }
 /// <summary>
 /// Handles the ApplyChangeFailed event of the syncAgent control.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs"/> instance containing the event data.</param>
 /// <remarks>Documented by Dev03, 2009-02-12</remarks>
 private static void syncAgent_ApplyChangeFailed(object sender, ApplyChangeFailedEventArgs e)
 {
     Trace.WriteLine(e.Error.ToString());
 }
 private void RelationalProviderProxy_ApplyChangeFailed(object sender, ApplyChangeFailedEventArgs e)
 {
     throw new NotImplementedException();
 }
Example #12
0
        /// #UPLOAD 2
        private void ApplyChangesInternal(SyncGroupMetadata groupMetadata, DataSet dataSet, SyncSession syncSession, SyncContext syncContext)
        {
            SyncStage syncStage = SyncStage.UploadingChanges;

            foreach (SyncTableMetadata tableMetadata in groupMetadata.TablesMetadata)
            {
                SpSyncAdapter adapter = null;

                if (this.SyncAdapters.Contains(tableMetadata.TableName))
                {
                    adapter = this.SyncAdapters[tableMetadata.TableName];
                }

                if (adapter == null)
                {
                    throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
                                                              Messages.InvalidTableName, tableMetadata.TableName));
                }


                // SpSyncAnchor anchor
                if (!dataSet.Tables.Contains(tableMetadata.TableName))
                {
                    throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
                                                              Messages.TableNotInSchema, tableMetadata.TableName));
                }

                SyncTableProgress tableProgress = syncContext.GroupProgress.FindTableProgress(tableMetadata.TableName);

                DataTable dataTable = dataSet.Tables[tableMetadata.TableName];

                try
                {
                    Collection <SyncConflict> conflicts;
                    int changesCount = dataTable.Rows.Count;
                    adapter.Update(dataTable, Connection, out conflicts);

                    if (conflicts != null)
                    {
                        foreach (SyncConflict conflict in conflicts)
                        {
                            ApplyChangeFailedEventArgs failureArgs = new ApplyChangeFailedEventArgs(tableMetadata, conflict, null, syncSession, syncContext, Connection, null);
                            OnApplyChangeFailed(failureArgs);

                            if (failureArgs.Action == ApplyAction.Continue)
                            {
                                if (conflict != null)
                                {
                                    tableProgress.ChangesFailed++;
                                    tableProgress.Conflicts.Add(conflict);
                                }
                            }
                        }
                    }
                    tableProgress.ChangesApplied = changesCount - tableProgress.ChangesFailed;
                }
                catch (Exception e)
                {
                    SyncConflict conflict = new SyncConflict(ConflictType.ErrorsOccurred, SyncStage.UploadingChanges)
                    {
                        ErrorMessage = e.Message + ", InnerException:" + e.InnerException.ToString(), ServerChange = dataTable, ClientChange = dataTable
                    };
                    ApplyChangeFailedEventArgs failureArgs = new ApplyChangeFailedEventArgs(tableMetadata, conflict, null, syncSession, syncContext, Connection, null);
                    OnApplyChangeFailed(failureArgs);
                    // handle errors?
                    if (SyncTracer.IsErrorEnabled())
                    {
                        SyncTracer.Error(e.ToString());
                    }
                }

                SyncProgressEventArgs args = new SyncProgressEventArgs(tableMetadata, tableProgress, groupMetadata, syncContext.GroupProgress, syncStage);
                OnSyncProgress(args);
            }
        }
 void serverSyncProvider_ApplyChangeFailed(object sender, ApplyChangeFailedEventArgs e)
 {
     //MessageBox.Show(e.Conflict.ErrorMessage);
 }
Example #14
0
        //Create client and server log files, and write to them
        //based on data from several EventArgs classes.
        public static void LogEvents(object sender, EventArgs e)
        {
            string logFile = String.Empty;
            string site    = String.Empty;

            if (sender is SampleServerSyncProvider)
            {
                logFile = "ServerLogFile.txt";
                site    = "server";
            }
            else if (sender is SampleClientSyncProvider)
            {
                logFile = "ClientLogFile.txt";
                site    = "client";
            }

            StreamWriter  streamWriter = File.AppendText(logFile);
            StringBuilder outputText   = new StringBuilder();

            if (e is ChangesSelectedEventArgs)
            {
                ChangesSelectedEventArgs args = (ChangesSelectedEventArgs)e;
                outputText.AppendLine("Client ID: " + args.Session.ClientId);
                outputText.AppendLine("Changes selected from " + site + " for group " + args.GroupMetadata.GroupName);
                outputText.AppendLine("Inserts selected from " + site + " for group: " + args.Context.GroupProgress.TotalInserts.ToString());
                outputText.AppendLine("Updates selected from " + site + " for group: " + args.Context.GroupProgress.TotalUpdates.ToString());
                outputText.AppendLine("Deletes selected from " + site + " for group: " + args.Context.GroupProgress.TotalDeletes.ToString());
            }

            else if (e is ChangesAppliedEventArgs)
            {
                ChangesAppliedEventArgs args = (ChangesAppliedEventArgs)e;
                outputText.AppendLine("Client ID: " + args.Session.ClientId);
                outputText.AppendLine("Changes applied to " + site + " for group " + args.GroupMetadata.GroupName);
                outputText.AppendLine("Inserts applied to " + site + " for group: " + args.Context.GroupProgress.TotalInserts.ToString());
                outputText.AppendLine("Updates applied to " + site + " for group: " + args.Context.GroupProgress.TotalUpdates.ToString());
                outputText.AppendLine("Deletes applied to " + site + " for group: " + args.Context.GroupProgress.TotalDeletes.ToString());
            }

            else if (e is SchemaCreatedEventArgs)
            {
                SchemaCreatedEventArgs args = (SchemaCreatedEventArgs)e;
                outputText.AppendLine("Schema creation for group: " + args.Table.SyncGroup.GroupName);
                outputText.AppendLine("Table: " + args.Table.TableName);
                outputText.AppendLine("Direction : " + args.Table.SyncDirection);
                outputText.AppendLine("Creation Option: " + args.Table.CreationOption);
            }

            //<snippetOCS_CS_Events_ApplyChangeFailedEventArgs>
            else if (e is ApplyChangeFailedEventArgs)
            {
                ApplyChangeFailedEventArgs args = (ApplyChangeFailedEventArgs)e;
                outputText.AppendLine("** APPLY CHANGE FAILURE AT " + site.ToUpper() + " **");
                outputText.AppendLine("Table for which failure occurred: " + args.TableMetadata.TableName);
                outputText.AppendLine("Error message: " + args.Error.Message);
            }
            //</snippetOCS_CS_Events_ApplyChangeFailedEventArgs>

            else
            {
                outputText.AppendLine("Unknown event occurred");
            }

            streamWriter.WriteLine(DateTime.Now.ToShortTimeString() + " | " + outputText.ToString());
            streamWriter.Flush();
            streamWriter.Dispose();
        }