【问题标题】:investigate or compare the data being pushed and pulled in Azure Offline data Sync调查或比较 Azure 离线数据同步中推送和拉取的数据
【发布时间】:2018-03-03 11:16:02
【问题描述】:

我有关注 Azure 移动客户端

public AzureCloudService()
{
    Client = new MobileServiceClient(AzureUrl, new CustomAzureClientMessageHandler());

}

我将以下消息处理程序附加到该客户端

   public class CustomAzureClientMessageHandler : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
            CancellationToken cancellationToken)
        {
            // Do any pre-request requirements here
            request.Headers.Add("UserId", Settings.UserId);

            // Request happens here
            var response = base.SendAsync(request, cancellationToken);

            // Do any post-request requirements here
            return response;
        }
    }

我在以下几行的帮助下将本地数据与服务器同步。

  // Push the Operations Queue to the mobile backed
            await Client.SyncContext.PushAsync();

 // Pull each sync table
            var table = await GetTableAsync<T>();
            await table.PullAsync();

问题是我需要调查/比较同步中推送和拉取的数据。

1) 有什么方法可以查看同步调用中推送和拉取的数据?可能正在使用我上面提到的消息处理程序?

2) 或者有什么方法可以在 Table Controller 中而不是在移动客户端上做同样的事情?

当同步出现问题时,真的很难调试

【问题讨论】:

    标签: c# sqlite azure xamarin azure-mobile-services


    【解决方案1】:

    https://blogs.msdn.microsoft.com/azuremobile/2014/04/07/deep-dive-on-the-offline-support-in-the-managed-client-sdk/

    在某些情况下,您希望捕获并处理客户端中的同步冲突。您可以通过实现 IMobileServiceSyncHandler 接口并在初始化上下文时传递它来控制所有同步操作。例如,这是一个同步处理程序的实现,它跟踪正在发生的所有操作。

    classMySyncHandler : IMobileServiceSyncHandler
    {
        MainPage page;
    
        public MySyncHandler(MainPage page)
        {
            this.page = page;
        }
    
        publicTask<JObject> ExecuteTableOperationAsync(IMobileServiceTableOperation operation)
        {
            page.AddToDebug("Executing operation '{0}' for table '{1}'", operation.Kind, operation.Table.Name);
            return operation.ExecuteAsync();
        }
    
        publicTask OnPushCompleteAsync(MobileServicePushCompletionResult result)
        {
            page.AddToDebug("Push result: {0}", result.Status);
            foreach (var error in result.Errors)
            {
                page.AddToDebug("  Push error: {0}", error.Status);
            }
    
            returnTask.FromResult(0);
        }
    }
    

    并且我们可以通过在同步上下文中将它传递给 InitializeAsync 的重载来使用这个同步处理程序,如下所示:

    var store = newMobileServiceSQLiteStore(StoreFileName);
    store.DefineTable<TodoItem>();
    AddToDebug("Defined table in the store");
    
    var syncHandler = newMySyncHandler(this);
    await client.SyncContext.InitializeAsync(store, syncHandler);
    AddToDebug("Initialized the sync context");
    

    【讨论】:

    • 。谢谢,但我可以看到这对在线场景很有用,但对于在应用程序备份到在线时将离线表与服务器同步无用。特别是当我想调查 Push 和 Pull 时。但是我找到了一个答案,我将在答案中更新
    • 我的解决方案是针对离线场景的,我链接的整篇文章也是如此。但我很高兴您找到了实现所需的方法。
    【解决方案2】:

    我找到了解决方案。我从下面的示例中得到它。感谢作者

    https://github.com/Azure-Samples/app-service-mobile-dotnet-todo-list-files/blob/master/src/client/MobileAppsFilesSample/Helpers/LoggingHandler.cs#L12

    解决办法是

    1. 扩展 SQLLite 存储以启用日志记录
    2. 使用消息处理程序进行日志记录

    代码

    /// <summary>
    /// Extended SQlite Store which can log operations happen in the SQLite database
    /// </summary>
    public class MobileServiceSQLiteStoreWithLogging : MobileServiceSQLiteStore
    {
        private bool logResults;
        private bool logParameters;
    
        public MobileServiceSQLiteStoreWithLogging(string fileName, bool logResults = false, bool logParameters = false)
            : base(fileName)
        {
            this.logResults = logResults;
            this.logParameters = logParameters;
        }
    
        protected override IList<JObject> ExecuteQueryInternal(string tableName, string sql,
            IDictionary<string, object> parameters)
        {
            Debug.WriteLine(sql);
    
            if (logParameters)
                PrintDictionary(parameters);
    
            var result = base.ExecuteQueryInternal(tableName, sql, parameters);
    
            if (logResults && result != null)
            {
                foreach (var token in result)
                    Debug.WriteLine(token);
            }
    
            return result;
        }
    
    
        protected override void ExecuteNonQueryInternal(string sql, IDictionary<string, object> parameters)
        {
            Debug.WriteLine(sql);
    
            if (logParameters)
                PrintDictionary(parameters);
    
            base.ExecuteNonQueryInternal(sql, parameters);
        }
    
    
        private void PrintDictionary(IDictionary<string, object> dictionary)
        {
            if (dictionary == null)
                return;
    
            foreach (var pair in dictionary)
                Debug.WriteLine("{0}:{1}", pair.Key, pair.Value);
        }
    }
    
    /// <summary>
    /// Message Handler which enable to pass the customer headers as well as logging the Request, Response etc happen via the Azure Mobile client
    /// </summary>
    public class CustomAzureClientMessageHandler : DelegatingHandler
    {
        private bool logRequestResponseBody;
    
        public CustomAzureClientMessageHandler(bool logRequestResponseBody = false)
        {
            this.logRequestResponseBody = logRequestResponseBody;
        }
    
        protected override async Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request,
            CancellationToken cancellationToken)
        {
            Debug.WriteLine("Request is being sent: {0} {1}", request.Method, request.RequestUri.ToString());
    
            if (logRequestResponseBody && request.Content != null)
            {
                var requestContent = await request.Content.ReadAsStringAsync();
                Debug.WriteLine(requestContent);
            }
    
    
            Debug.WriteLine("HEADERS in the request");
    
            foreach (var header in request.Headers)
            {
                Debug.WriteLine(string.Format("{0}:{1}", header.Key, string.Join(",", header.Value)));
            }
    
            var response = await base.SendAsync(request, cancellationToken);
    
            Debug.WriteLine("Response from server: {0}", response.StatusCode);
    
            if (logRequestResponseBody)
            {
                var responseContent = await response.Content.ReadAsStringAsync();
                Debug.WriteLine(responseContent);
            }
    
            return response;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-15
      • 1970-01-01
      • 1970-01-01
      • 2016-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多