C# Xamarin中的Azure移动服务412故障
每当我试图通过MobileServices更新一个项目时,总是会出现412个错误(失败)。我相信这是最近开始的,但不幸的是,这个错误给了我很少的信息 我已经设置了一个冲突解决程序,其思想是在发生任何冲突的情况下,将客户端版本作为赢家,如所示。为了做到这一点,我重复了push的呼叫。然而,我得到了412失败的两个推动,而不仅仅是第一次 这是我的处理程序代码C# Xamarin中的Azure移动服务412故障,c#,xamarin,azure-mobile-services,C#,Xamarin,Azure Mobile Services,每当我试图通过MobileServices更新一个项目时,总是会出现412个错误(失败)。我相信这是最近开始的,但不幸的是,这个错误给了我很少的信息 我已经设置了一个冲突解决程序,其思想是在发生任何冲突的情况下,将客户端版本作为赢家,如所示。为了做到这一点,我重复了push的呼叫。然而,我得到了412失败的两个推动,而不仅仅是第一次 这是我的处理程序代码 public class AzureConflictHandler : IMobileServiceSyncHandler {
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
}
我不知道为什么那个教程会这样说,但它目前是不正确的 再次调用execute不会更改结果,本地项不会自动修改。(从技术上讲,如果您只想要last write wins(客户端),您可以从数据模型中删除版本,而永远不会得到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 ...
}
我不知道为什么那个教程会这样说,但它目前是不正确的 再次调用execute不会更改结果,本地项不会自动修改。(从技术上讲,如果您只想要last write wins(客户端),您可以从数据模型中删除版本,而永远不会得到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 ...
}
故障信息是什么????失败信息是什么????