使用Azure Mobile Client时无法解决同步冲突 - 错误不断回来

时间:2016-10-19 16:14:43

标签: azure xamarin azure-mobile-services

我在Azure上使用带有Easy Tables的Node.JS后端。该表包含支持脱机同步所需的列。 在测试同步过程时,我注意到即使我正在解决冲突,冲突也会不断回归。

我的测试:

  • 将表内容从Azure拉到iOS和Android设备
  • 更改iOS上的记录,但不要同步回Azure
  • 更改Android上的相同记录并同步
  • 现在同步iOS

正如预期的那样,正确检测到冲突,我抓住了MobileServicePushFailedException。然后我通过用服务器项替换本地项来解决错误:

localItem.AzureVersion = serverItem.AzureVersion;
await result.UpdateOperationAsync(JObject.FromObject (localItem));

但是,下次同步时,相同的项目会再次失败并出现相同的错误。

AzureVersion属性声明如下:

[Version]
public string AzureVersion { get; set; }

result.UpdateOperationAsync()到底在做什么?它更新我的本地数据库吗?我必须手动完成吗? 而且:我之后应该触发一个明确的PushAsync()吗?

修改 我将该属性从AzureVersion更改为Version并且可以正常运行。我注意到serverItem的{​​{1}}属性为NULL,即使JSON包含它。 Json.Net或Azure移动客户端中的错误?

1 个答案:

答案 0 :(得分:1)

You should be using something like the following:

public async Task SyncAsync()
{
    ReadOnlyCollection<MobileServiceTableOperationError> syncErrors = null;

    try
    {
        await this.client.SyncContext.PushAsync();

        await this.todoTable.PullAsync(
            //The first parameter is a query name that is used internally by the client SDK to implement incremental sync.
            //Use a different query name for each unique query in your program
            "allTodoItems",
            this.todoTable.CreateQuery());
    }
    catch (MobileServicePushFailedException exc)
    {
        if (exc.PushResult != null)
        {
            syncErrors = exc.PushResult.Errors;
        }
    }

    // Simple error/conflict handling. A real application would handle the various errors like network conditions,
    // server conflicts and others via the IMobileServiceSyncHandler.
    if (syncErrors != null)
    {
        foreach (var error in syncErrors)
        {
            if (error.OperationKind == MobileServiceTableOperationKind.Update && error.Result != null)
            {
                //Update failed, reverting to server's copy.
                await error.CancelAndUpdateItemAsync(error.Result);
            }
            else
            {
                // Discard local change.
                await error.CancelAndDiscardItemAsync();
            }

            Debug.WriteLine(@"Error executing sync operation. Item: {0} ({1}). Operation discarded.", error.TableName, error.Item["id"]);
        }
    }
}

Note the CancelAndUpdateItemAsync(), which updates the item to the server copy or CancelAndDiscardItemAsync(), which accepts the local item. These are the important things for you.

This code came from the official HOWTO docs here: https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-dotnet-how-to-use-client-library/##offlinesync