protected virtual async Task BuildRetrieveDataTask(DtoSyncConfigSyncFromInformation dtoSyncConfigSyncFromInformation, CancellationToken cancellationToken)
        {
            if (dtoSyncConfigSyncFromInformation == null)
            {
                throw new ArgumentNullException(nameof(dtoSyncConfigSyncFromInformation));
            }

            try
            {
                IBoundClient <IDictionary <string, object> > query = (dtoSyncConfigSyncFromInformation.DtoSetSyncConfig.OnlineDtoSetForGet ?? dtoSyncConfigSyncFromInformation.DtoSetSyncConfig.OnlineDtoSet)(ODataClient);

                if (dtoSyncConfigSyncFromInformation.MaxVersion == 0)
                {
                    query = query.Where($"{nameof(ISyncableDto.IsArchived)} eq false");
                }
                else
                {
                    query = query.Where($"{nameof(ISyncableDto.Version)} gt {dtoSyncConfigSyncFromInformation.MaxVersion}");
                }

                string oDataGetAndVersionFilter = await query
                                                  .GetCommandTextAsync(cancellationToken)
                                                  .ConfigureAwait(false);

                string oDataUri = $"{ClientAppProfile.ODataRoute}{oDataGetAndVersionFilter}";

                using (HttpResponseMessage response = await HttpClient.GetAsync(oDataUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false))
                {
                    response.EnsureSuccessStatusCode();

#if DotNetStandard2_0 || UWP
                    using Stream stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
#elif Android || iOS || DotNetStandard2_1
                    await using Stream stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
#else
                    await using Stream stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
#endif
                    {
                        using (StreamReader reader = new StreamReader(stream))
                        {
                            using (JsonReader jsonReader = new JsonTextReader(reader))
                            {
                                JToken jToken = await JToken.LoadAsync(jsonReader, new JsonLoadSettings
                                {
                                    CommentHandling  = CommentHandling.Ignore,
                                    LineInfoHandling = LineInfoHandling.Ignore
                                }, cancellationToken).ConfigureAwait(false);

                                dtoSyncConfigSyncFromInformation.RecentlyChangedOnlineDtos = ((IEnumerable)(jToken)["value"] !.ToObject(typeof(List <>).MakeGenericType(dtoSyncConfigSyncFromInformation.DtoType)) !).Cast <ISyncableDto>().ToArray();
                            }
                        }
                    }
                }
            }
            catch (Exception exp)
            {
                dtoSyncConfigSyncFromInformation.RecentlyChangedOnlineDtos = Array.Empty <ISyncableDto>();
                ExceptionHandler.OnExceptionReceived(exp);
            }
        }
示例#2
0
        public virtual async Task CallSyncFrom(DtoSetSyncConfig[] fromServerDtoSetSyncMaterials, CancellationToken cancellationToken)
        {
            if (fromServerDtoSetSyncMaterials == null)
            {
                throw new ArgumentNullException(nameof(fromServerDtoSetSyncMaterials));
            }

            if (fromServerDtoSetSyncMaterials.Any())
            {
                await GetMetadataIfNotRetrievedAlready(cancellationToken).ConfigureAwait(false);

                await using (EfCoreDbContextBase offlineContextForSyncFrom = Container.Resolve <EfCoreDbContextBase>())
                {
                    ((IsSyncDbContext)offlineContextForSyncFrom).IsSyncDbContext = true;

                    List <DtoSyncConfigSyncFromInformation> dtoSyncConfigSyncFromInformationList = new List <DtoSyncConfigSyncFromInformation>();

                    int id = 0;

                    foreach (DtoSetSyncConfig fromServerSyncConfig in fromServerDtoSetSyncMaterials)
                    {
                        IQueryable <ISyncableDto> offlineSet = fromServerSyncConfig.OfflineDtoSet(offlineContextForSyncFrom);

                        var mostRecentOfflineDto = await offlineSet
                                                   .IgnoreQueryFilters()
                                                   .AsNoTracking()
                                                   .Select(e => new { e.Version })
                                                   .OrderByDescending(e => e.Version)
                                                   .FirstOrDefaultAsync(cancellationToken)
                                                   .ConfigureAwait(false);

                        long maxVersion = mostRecentOfflineDto?.Version ?? 0;

                        DtoSyncConfigSyncFromInformation dtoSyncConfigSyncFromInformation = new DtoSyncConfigSyncFromInformation
                        {
                            Id = id++,
                            DtoSetSyncConfig    = fromServerSyncConfig,
                            DtoType             = offlineSet.ElementType.GetTypeInfo(),
                            HadOfflineDtoBefore = mostRecentOfflineDto != null,
                            MaxVersion          = maxVersion
                        };

                        IBoundClient <IDictionary <string, object> > query = (dtoSyncConfigSyncFromInformation.DtoSetSyncConfig.OnlineDtoSetForGet ?? dtoSyncConfigSyncFromInformation.DtoSetSyncConfig.OnlineDtoSet)(ODataClient);

                        if (dtoSyncConfigSyncFromInformation.MaxVersion == 0)
                        {
                            query = query.Where($"{nameof(ISyncableDto.IsArchived)} eq false");
                        }
                        else
                        {
                            query = query.Where($"{nameof(ISyncableDto.Version)} gt {dtoSyncConfigSyncFromInformation.MaxVersion}");
                        }

                        string oDataGetAndVersionFilter = await query
                                                          .GetCommandTextAsync(cancellationToken)
                                                          .ConfigureAwait(false);

                        dtoSyncConfigSyncFromInformation.ODataGetUri = $"{ClientAppProfile.HostUri}{ClientAppProfile.ODataRoute}{oDataGetAndVersionFilter}";

                        dtoSyncConfigSyncFromInformationList.Add(dtoSyncConfigSyncFromInformation);
                    }

                    StringBuilder batchRequests = new StringBuilder();

                    batchRequests.AppendLine(@"
{
    ""requests"": [");

                    foreach (DtoSyncConfigSyncFromInformation?dtoSyncConfigSyncFromInformation in dtoSyncConfigSyncFromInformationList)
                    {
                        batchRequests.AppendLine(@$ "
        {{
            " "id" ": " "{dtoSyncConfigSyncFromInformation.Id}" ",
            " "method" ": " "GET" ",
            " "url" ": " "{dtoSyncConfigSyncFromInformation.ODataGetUri}" "
        }}{(dtoSyncConfigSyncFromInformation != dtoSyncConfigSyncFromInformationList.Last() ? ", " : " ")}");
                    }

                    batchRequests.AppendLine(@"
                  ]
}");

                    using (HttpResponseMessage batchResponbse = await HttpClient.PostAsync($"{ClientAppProfile.ODataRoute}$batch", new StringContent(batchRequests.ToString(), Encoding.UTF8, "application/json"), cancellationToken).ConfigureAwait(false))
                    {
                        batchResponbse.EnsureSuccessStatusCode();

                        if (batchResponbse.Content.Headers.ContentType.MediaType != "application/json")
                        {
                            throw new InvalidOperationException($"{batchResponbse.Content.Headers.ContentType.MediaType} content type is not supported.");
                        }

#if UWP || DotNetStandard2_0
                        using (Stream stream = await batchResponbse.Content.ReadAsStreamAsync().ConfigureAwait(false))
#else
                        await using (Stream stream = await batchResponbse.Content.ReadAsStreamAsync().ConfigureAwait(false))
#endif
                        {
                            using (StreamReader reader = new StreamReader(stream))
                            {
                                using (JsonReader jsonReader = new JsonTextReader(reader))
                                {
                                    JToken jToken = await JToken.LoadAsync(jsonReader, new JsonLoadSettings
                                    {
                                        CommentHandling  = CommentHandling.Ignore,
                                        LineInfoHandling = LineInfoHandling.Ignore
                                    }, cancellationToken).ConfigureAwait(false);

                                    foreach (JToken response in jToken["responses"] !)
                                    {
                                        int responseId = response.Value <int>("id");

                                        DtoSyncConfigSyncFromInformation?dtoSyncConfigSyncFromInformation = dtoSyncConfigSyncFromInformationList.ExtendedSingle($"Getting dtoSyncConfigSyncFromInformation with id {responseId}", item => item.Id == responseId);

                                        dtoSyncConfigSyncFromInformation.RecentlyChangedOnlineDtos = ((IEnumerable)response["body"] !["value"] !.ToObject(typeof(List <>).MakeGenericType(dtoSyncConfigSyncFromInformation.DtoType)) !).Cast <ISyncableDto>().ToArray();