Xamarin中的Azure移动服务412故障

本文关键字:故障 服务 移动 中的 Azure Xamarin | 更新日期: 2023-09-27 18:27:00

每当试图通过MobileServices更新项目时,我总是会收到412个错误(PreconditionFailed)。我相信这是最近开始的,但不幸的是,这个错误给我的信息很少。

我已经设置了一个冲突解决程序,其想法是在发生任何冲突时,将客户端版本作为赢家,根据https://azure.microsoft.com/en-us/documentation/articles/mobile-services-windows-store-dotnet-handling-conflicts-offline-data/.为了做到这一点,我重复了推动的呼吁。然而,我在两次推送中都失败了412次,而不仅仅是第一次。

这是我的处理程序代码。

    public class AzureConflictHandler : IMobileServiceSyncHandler
{
    readonly ILogger _logger;
    public AzureConflictHandler(ILogger logger){
        _logger = logger;
    }
    #region IMobileServiceSyncHandler implementation
    public Task OnPushCompleteAsync (MobileServicePushCompletionResult result)
    {
        return Task.FromResult (false);
    }
    public async Task<JObject> ExecuteTableOperationAsync (IMobileServiceTableOperation operation)
    {
        try{
            await operation.ExecuteAsync ();
            return null;
        }                 
        catch (MobileServiceConflictException ex)
        {
            _logger.HandleException (ex);
        }
        catch (MobileServicePreconditionFailedException ex)
        {
            _logger.HandleException (ex);
            //https://codemilltech.com/why-cant-we-be-friends-conflict-resolution-in-azure-mobile-services/
        }
        catch(Exception e){
            _logger.HandleException (e);
            throw;
        }
        try
        {
            //retry so we'll take the client value
            await operation.ExecuteAsync();
            return null;
        }
        catch (MobileServicePreconditionFailedException e)
        {
            _logger.HandleException(e, LogLevel.Fatal);
            return e.Value;
        }
    }
    #endregion

}

其他人看到这个错误了吗?我的数据对象中有一个Version字段,如下所示。

        public string id { get; set; }
    public string EntityType { get; set; }
    public Guid EntityID { get; set; }
    public string EntityJSON { get; set; }
    public DateTimeOffset LastUpdatedDate { get; set; }
    [Microsoft.WindowsAzure.MobileServices.Version]
    public string Version { set; get; }

Xamarin中的Azure移动服务412故障

我不知道教程为什么这么说,但目前是不正确的。

第二次调用execute,不会更改结果,本地项永远不会自动修改。(从技术上讲,如果你只想赢得最后一次写入(客户端),你可以从你的数据模型中删除版本,你永远不会得到412。)

假设从长远来看,您需要一个更复杂的策略,那么您需要使用服务器的版本副本更新本地项的版本。

catch (MobileServicePreconditionFailedException ex) {
  var serverValue = ex.Value;
  // Resolve in favor of our client by just using the server's version
  var item = operation.Item;
  item[MobileServiceSystemColumns.Version] = serverValue[MobileServiceSystemColumns.Version];
  // this will save the item changes to the local store so next Push()
  // will resolve this
  operation.UpdateOperationAsync(item)
  throw ex;

}

在上面的代码中,尽管您立即重试,但要注意它应该处于循环中,因为另一个客户端也可能在更新它,等等。

在这种情况下,你可以做一些更像的事情

while (some condition) {
  try {
     return await operation.ExecuteAsync();
  } catch (obileServicePreconditionFailedException ex) {
    var serverItem = ex.Value;
    operation.item[MobileServiceSystemColumns.Version] = serverValue[MobileServiceSystemColumns.Version];
  } catch ...
}

https://github.com/Azure/mobile-services-samples/blob/master/TodoOffline/WindowsUniversal/TodoOffline/TodoOffline.Shared/SyncHandler.cs#L27