/// <summary> /// Callback for the Download HttpWebRequest.beginGetRequestStream. Deserializes the response feed to /// retrieve the list of IOfflineEntity objects and constructs an ChangeSet for that. /// </summary> private async Task ReadDownloadResponse(HttpWebResponse response, AsyncArgsWrapper wrapper) { try { if (response.StatusCode == HttpStatusCode.OK) { Stream responseStream = response.GetResponseStream(); // Create the SyncReader this.syncReader = (SerializationFormat == SerializationFormat.ODataAtom) ? new ODataAtomReader(responseStream, this.knownTypes) : (SyncReader) new ODataJsonReader(responseStream, this.knownTypes); await Task.Factory.StartNew(() => { // Read the response while (syncReader.Next()) { switch (syncReader.ItemType) { case ReaderItemType.Entry: wrapper.DownloadResponse.AddItem(syncReader.GetItem()); break; case ReaderItemType.SyncBlob: wrapper.DownloadResponse.ServerBlob = syncReader.GetServerBlob(); break; case ReaderItemType.HasMoreChanges: wrapper.DownloadResponse.IsLastBatch = !syncReader.GetHasMoreChangesValue(); break; } } }); } else { wrapper.Error = new CacheControllerException( string.Format("Remote service returned error status. Status: {0}, Description: {1}", response.StatusCode, response.StatusDescription)); } } catch (Exception e) { if (ExceptionUtility.IsFatal(e)) { throw; } wrapper.Error = e; } }
static void Main() { Stopwatch stopWatch = Stopwatch.StartNew(); AsyncReader asyncReader = new AsyncReader(filePath); asyncReader.MainAsync().GetAwaiter().GetResult(); stopWatch.Stop(); string resultAsync = ($"{stopWatch.Elapsed}"); stopWatch.Start(); SyncReader syncReader = new SyncReader(filePath); syncReader.MainSync(); stopWatch.Stop(); string resultSync = ($"{stopWatch.Elapsed}"); Console.WriteLine($"\nAsync \t\t {resultAsync}\nSync \t\t {resultSync}"); }
Response IDnsClient.Process(Request request) { if (object.ReferenceEquals(null, request)) { throw new ArgumentNullException("request"); } // create request datagram, prefixed with the two byte length field Datagram qdata = Datagram.GetPrefixed(request.Data); NetworkStream ns = base.GetStream(); if (RequestSending != null) { RequestSending(this, new MessageEventArgs(request, ns, (IPEndPoint)Client.RemoteEndPoint)); } // LogMessage LogRequest(qdata.Length); // send prefixed request message request.SetTimestamp(); ns.Write(qdata, 0, qdata.Length); // read response SyncReader reader = new SyncReader(ns); for (reader.Start(); reader.Next();) { ; } Response response = Response.Create((Datagram)reader.Data, DateTime.Now); // LogMessage LogResponse(response); return(response); }
/// <summary> /// Callback for the Download HttpWebRequest.beginGetRequestStream. Deserializes the response feed to /// retrieve the list of IOfflineEntity objects and constructs an ChangeSet for that. /// </summary> /// <param name="asyncResult">IAsyncResult object</param> void OnDownloadGetResponseCompleted(IAsyncResult asyncResult) { AsyncArgsWrapper wrapper = asyncResult.AsyncState as AsyncArgsWrapper; wrapper.DownloadResponse = new ChangeSet(); HttpWebResponse response = null; try { try { response = wrapper.WebRequest.EndGetResponse(asyncResult) as HttpWebResponse; if (String.IsNullOrEmpty(behaviors.UserId)) { behaviors.UserId = response.Headers["userid"]; } if (string.IsNullOrWhiteSpace(behaviors.UserEmail)) { behaviors.UserEmail = response.Headers["email"]; } behaviors.ResourceVersion = response.Headers["resourceversion"]; } catch (WebException we) { wrapper.Error = we; // If we get here then it means we completed the request. Return to the original caller this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper); return; } catch (SecurityException se) { wrapper.Error = se; // If we get here then it means we completed the request. Return to the original caller this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper); return; } if (response.StatusCode == HttpStatusCode.OK) { behaviors.SaveUserSession(); int contentLength = (int)response.ContentLength; if (response.Headers.AllKeys.Contains("unzippedcontentlength")) { string value = response.Headers["unzippedcontentlength"]; if (!int.TryParse(value, out contentLength)) { throw new WebException("Invalid value of header unzippedcontentlength: " + value); } } Stream responseStream = new ProgressStream(response.GetResponseStream() , contentLength , behaviors.ReadProgressCallback); // CreateInstance the SyncReader if (ApplicationContext.Current.Settings.BitMobileFormatterDisabled) { _syncReader = new ODataAtomReader(responseStream, _knownTypes); } else { _syncReader = new BMReader(responseStream, _knownTypes); } // Read the response wrapper.DownloadResponse.Data = GetDownloadedValues(wrapper); wrapper.WebResponse = response; // Invoke user code on the correct synchronization context. this.FirePostResponseHandler(wrapper); } else { wrapper.Error = new CacheControllerException( string.Format("Remote service returned error status. Status: {0}, Description: {1}", response.StatusCode, response.StatusDescription)); } // If we get here then it means we completed the request. Return to the original caller this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper); } catch (Exception e) { if (ExceptionUtility.IsFatal(e)) { throw; } wrapper.Error = e; this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper); } }
/// <summary> /// Callback for the Upload HttpWebRequest.BeginGetResponse call /// </summary> /// <param name="asyncResult">IAsyncResult object</param> void OnUploadGetResponseCompleted(IAsyncResult asyncResult) { AsyncArgsWrapper wrapper = asyncResult.AsyncState as AsyncArgsWrapper; wrapper.UploadResponse = new ChangeSetResponse(); HttpWebResponse response = null; try { try { response = wrapper.WebRequest.EndGetResponse(asyncResult) as HttpWebResponse; } catch (WebException we) { wrapper.UploadResponse.Error = we; // If we get here then it means we completed the request. Return to the original caller this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper); return; } catch (SecurityException se) { wrapper.UploadResponse.Error = se; // If we get here then it means we completed the request. Return to the original caller this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper); return; } if (response.StatusCode == HttpStatusCode.OK) { Stream responseStream = response.GetResponseStream(); // CreateInstance the SyncReader if (ApplicationContext.Current.Settings.BitMobileFormatterDisabled) { _syncReader = new ODataAtomReader(responseStream, _knownTypes); } else { _syncReader = new BMReader(responseStream, _knownTypes); } // Read the response while (this._syncReader.Next()) { switch (this._syncReader.ItemType) { case ReaderItemType.Entry: IOfflineEntity entity = this._syncReader.GetItem(); IOfflineEntity ackedEntity = entity; string tempId = null; // If conflict only one temp ID should be set if (this._syncReader.HasTempId() && this._syncReader.HasConflictTempId()) { throw new CacheControllerException(string.Format("Service returned a TempId '{0}' in both live and conflicting entities.", this._syncReader.GetTempId())); } // Validate the live temp ID if any, before adding anything to the offline context if (this._syncReader.HasTempId()) { tempId = this._syncReader.GetTempId(); CheckEntityServiceMetadataAndTempIds(wrapper, entity, tempId); } // If conflict if (this._syncReader.HasConflict()) { Conflict conflict = this._syncReader.GetConflict(); IOfflineEntity conflictEntity = (conflict is SyncConflict) ? ((SyncConflict)conflict).LosingEntity : ((SyncError)conflict).ErrorEntity; // Validate conflict temp ID if any if (this._syncReader.HasConflictTempId()) { tempId = this._syncReader.GetConflictTempId(); CheckEntityServiceMetadataAndTempIds(wrapper, conflictEntity, tempId); } // Add conflict wrapper.UploadResponse.AddConflict(conflict); // // If there is a conflict and the tempId is set in the conflict entity then the client version lost the // conflict and the live entity is the server version (ServerWins) // if (this._syncReader.HasConflictTempId() && entity.ServiceMetadata.IsTombstone) { // // This is a ServerWins conflict, or conflict error. The winning version is a tombstone without temp Id // so there is no way to map the winning entity with a temp Id. The temp Id is in the conflict so we are // using the conflict entity, which has the PK, to build a tombstone entity used to update the offline context // // In theory, we should copy the service metadata but it is the same end result as the service fills in // all the properties in the conflict entity // // Add the conflict entity conflictEntity.ServiceMetadata.IsTombstone = true; ackedEntity = conflictEntity; } } // Add ackedEntity to storage. If ackedEntity is still equal to entity then add non-conflict entity. if (!String.IsNullOrEmpty(tempId)) { wrapper.UploadResponse.AddUpdatedItem(ackedEntity); } break; case ReaderItemType.SyncBlob: wrapper.UploadResponse.ServerBlob = this._syncReader.GetServerBlob(); break; } } wrapper.WebResponse = response; // Invoke user code on the correct synchronization context. this.FirePostResponseHandler(wrapper); } else { wrapper.UploadResponse.Error = new CacheControllerException( string.Format("Remote service returned error status. Status: {0}, Description: {1}", response.StatusCode, response.StatusDescription)); } // If we get here then it means we completed the request. Return to the original caller this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper); } catch (Exception e) { if (ExceptionUtility.IsFatal(e)) { throw; } wrapper.Error = e; this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper); } }
Response IDnsClient.Process(Request request) { if (object.ReferenceEquals(null, request)) throw new ArgumentNullException("request"); // create request datagram, prefixed with the two byte length field Datagram qdata = Datagram.GetPrefixed(request.Data); NetworkStream ns = base.GetStream(); if (RequestSending != null) RequestSending(this, new MessageEventArgs(request, ns, (IPEndPoint)Client.RemoteEndPoint)); // LogMessage LogRequest(qdata.Length); // send prefixed request message request.SetTimestamp(); ns.Write(qdata, 0, qdata.Length); // read response SyncReader reader = new SyncReader(ns); for (reader.Start(); reader.Next(); ) ; Response response = Response.Create((Datagram)reader.Data, DateTime.Now); // LogMessage LogResponse(response); return response; }
/// <summary> /// Callback for the Download HttpWebRequest.beginGetRequestStream. Deserializes the response feed to /// retrieve the list of IOfflineEntity objects and constructs an ChangeSet for that. /// </summary> /// <param name="asyncResult">IAsyncResult object</param> void OnDownloadGetResponseCompleted(IAsyncResult asyncResult) { AsyncArgsWrapper wrapper = asyncResult.AsyncState as AsyncArgsWrapper; wrapper.DownloadResponse = new ChangeSet(); HttpWebResponse response = null; try { try { response = wrapper.WebRequest.EndGetResponse(asyncResult) as HttpWebResponse; } catch (WebException we) { wrapper.Error = we; // If we get here then it means we completed the request. Return to the original caller this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper); return; } catch (SecurityException se) { wrapper.Error = se; // If we get here then it means we completed the request. Return to the original caller this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper); return; } if (response.StatusCode == HttpStatusCode.OK) { Stream responseStream = response.GetResponseStream(); // Create the SyncReader this._syncReader = (base.SerializationFormat == ClientServices.SerializationFormat.ODataAtom) ? (SyncReader) new ODataAtomReader(responseStream, this._knownTypes) : (SyncReader) new ODataJsonReader(responseStream, this._knownTypes); // Read the response while (this._syncReader.Next()) { switch (this._syncReader.ItemType) { case ReaderItemType.Entry: wrapper.DownloadResponse.AddItem(this._syncReader.GetItem()); break; case ReaderItemType.SyncBlob: wrapper.DownloadResponse.ServerBlob = this._syncReader.GetServerBlob(); break; case ReaderItemType.HasMoreChanges: wrapper.DownloadResponse.IsLastBatch = !this._syncReader.GetHasMoreChangesValue(); break; } } wrapper.WebResponse = response; // Invoke user code on the correct synchronization context. this.FirePostResponseHandler(wrapper); } else { wrapper.Error = new CacheControllerException( string.Format("Remote service returned error status. Status: {0}, Description: {1}", response.StatusCode, response.StatusDescription)); } // If we get here then it means we completed the request. Return to the original caller this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper); } catch (Exception e) { if (ExceptionUtility.IsFatal(e)) { throw; } wrapper.Error = e; this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper); } }
private object ProcessUploadRequest(HttpWebRequest webRequest, CacheRequest request) { using (Stream memoryStream = new MemoryStream()) { // Create a SyncWriter to write the contents this._syncWriter = new ODataAtomWriter(base.BaseUri); this._syncWriter.StartFeed(true, request.KnowledgeBlob ?? new byte[0]); foreach (IOfflineEntity entity in request.Changes) { // Skip tombstones that dont have a ID element. if (entity.ServiceMetadata.IsTombstone && string.IsNullOrEmpty(entity.ServiceMetadata.Id)) { continue; } string tempId = null; // Check to see if this is an insert. i.e ServiceMetadata.Id is null or empty if (string.IsNullOrEmpty(entity.ServiceMetadata.Id)) { if (TempIdToEntityMapping == null) { TempIdToEntityMapping = new Dictionary <string, IOfflineEntity>(); } tempId = Guid.NewGuid().ToString(); TempIdToEntityMapping.Add(tempId, entity); } this._syncWriter.AddItem(entity, tempId); } this._syncWriter.WriteFeed(XmlWriter.Create(memoryStream)); memoryStream.Flush(); // Set the content length webRequest.ContentLength = memoryStream.Position; using (Stream requestStream = webRequest.GetRequestStream()) { CopyStreamContent(memoryStream, requestStream); // Close the request stream requestStream.Flush(); requestStream.Close(); } } // Fire the Before request handler this.FirePreRequestHandler(webRequest); // Get the response HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse(); if (webResponse.StatusCode == HttpStatusCode.OK) { ChangeSetResponse changeSetResponse = new ChangeSetResponse(); using (Stream responseStream = webResponse.GetResponseStream()) { // Create the SyncReader this._syncReader = new ODataAtomReader(responseStream, this._knownTypes); // Read the response while (this._syncReader.Next()) { switch (this._syncReader.ItemType) { case ReaderItemType.Entry: IOfflineEntity entity = this._syncReader.GetItem(); IOfflineEntity ackedEntity = entity; string tempId = null; // If conflict only one temp ID should be set if (this._syncReader.HasTempId() && this._syncReader.HasConflictTempId()) { throw new CacheControllerException(string.Format("Service returned a TempId '{0}' in both live and conflicting entities.", this._syncReader.GetTempId())); } // Validate the live temp ID if any, before adding anything to the offline context if (this._syncReader.HasTempId()) { tempId = this._syncReader.GetTempId(); CheckEntityServiceMetadataAndTempIds(TempIdToEntityMapping, entity, tempId, changeSetResponse); } // If conflict if (this._syncReader.HasConflict()) { Conflict conflict = this._syncReader.GetConflict(); IOfflineEntity conflictEntity = (conflict is SyncConflict) ? ((SyncConflict)conflict).LosingEntity : ((SyncError)conflict).ErrorEntity; // Validate conflict temp ID if any if (this._syncReader.HasConflictTempId()) { tempId = this._syncReader.GetConflictTempId(); CheckEntityServiceMetadataAndTempIds(TempIdToEntityMapping, conflictEntity, tempId, changeSetResponse); } // Add conflict changeSetResponse.AddConflict(conflict); // // If there is a conflict and the tempId is set in the conflict entity then the client version lost the // conflict and the live entity is the server version (ServerWins) // if (this._syncReader.HasConflictTempId() && entity.ServiceMetadata.IsTombstone) { // // This is a ServerWins conflict, or conflict error. The winning version is a tombstone without temp Id // so there is no way to map the winning entity with a temp Id. The temp Id is in the conflict so we are // using the conflict entity, which has the PK, to build a tombstone entity used to update the offline context // // In theory, we should copy the service metadata but it is the same end result as the service fills in // all the properties in the conflict entity // // Add the conflict entity conflictEntity.ServiceMetadata.IsTombstone = true; ackedEntity = conflictEntity; } } // Add ackedEntity to storage. If ackedEntity is still equal to entity then add non-conflict entity. if (!String.IsNullOrEmpty(tempId)) { changeSetResponse.AddUpdatedItem(ackedEntity); } break; case ReaderItemType.SyncBlob: changeSetResponse.ServerBlob = this._syncReader.GetServerBlob(); break; } } } if (TempIdToEntityMapping != null && TempIdToEntityMapping.Count != 0) { // The client sent some inserts which werent ack'd by the service. Throw. StringBuilder builder = new StringBuilder("Server did not acknowledge with a permanant Id for the following tempId's: "); builder.Append(string.Join(",", TempIdToEntityMapping.Keys.ToArray())); throw new CacheControllerException(builder.ToString()); } this.FirePostResponseHandler(webResponse); webResponse.Close(); return(changeSetResponse); } else { throw new CacheControllerException( string.Format("Remote service returned error status. Status: {0}, Description: {1}", webResponse.StatusCode, webResponse.StatusDescription)); } }
private object ProcessDownloadRequest(HttpWebRequest webRequest, CacheRequest request) { using (Stream memoryStream = new MemoryStream()) { // Create a SyncWriter to write the contents this._syncWriter = new ODataAtomWriter(base.BaseUri); this._syncWriter.StartFeed(true, request.KnowledgeBlob ?? new byte[0]); this._syncWriter.WriteFeed(XmlWriter.Create(memoryStream)); memoryStream.Flush(); webRequest.ContentLength = memoryStream.Position; Stream requestStream = webRequest.GetRequestStream(); CopyStreamContent(memoryStream, requestStream); requestStream.Flush(); requestStream.Close(); // Fire the Before request handler this.FirePreRequestHandler(webRequest); } // Get the response HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse(); if (webResponse.StatusCode == HttpStatusCode.OK) { ChangeSet changeSet = new ChangeSet(); using (Stream responseStream = webResponse.GetResponseStream()) { // Create the SyncReader this._syncReader = new ODataAtomReader(responseStream, this._knownTypes); // Read the response while (this._syncReader.Next()) { switch (this._syncReader.ItemType) { case ReaderItemType.Entry: changeSet.AddItem(this._syncReader.GetItem()); break; case ReaderItemType.SyncBlob: changeSet.ServerBlob = this._syncReader.GetServerBlob(); break; case ReaderItemType.HasMoreChanges: changeSet.IsLastBatch = !this._syncReader.GetHasMoreChangesValue(); break; } } this.FirePostResponseHandler(webResponse); } webResponse.Close(); return(changeSet); } else { throw new CacheControllerException( string.Format("Remote service returned error status. Status: {0}, Description: {1}", webResponse.StatusCode, webResponse.StatusDescription)); } }
/// <summary> /// Callback for the Upload HttpWebRequest.BeginGetResponse call /// </summary> /// <param name="task">IAsyncResult object</param> async Task OnUploadGetResponseCompleted(Task <WebResponse> task, AsyncArgsWrapper wrapper) { wrapper.UploadResponse = new ChangeSetResponse(); HttpWebResponse response = null; try { try { response = await task.ConfigureAwait(false) as HttpWebResponse; } catch (WebException we) { wrapper.UploadResponse.Error = we; // If we get here then it means we completed the request. Return to the original caller this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper); return; } catch (SecurityException se) { wrapper.UploadResponse.Error = se; // If we get here then it means we completed the request. Return to the original caller this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper); return; } if (response.StatusCode == HttpStatusCode.OK) { Stream responseStream = response.GetResponseStream(); // Create the SyncReader this._syncReader = (base.SerializationFormat == ClientServices.SerializationFormat.ODataAtom) ? (SyncReader) new ODataAtomReader(responseStream, this._knownTypes) : (SyncReader) new ODataJsonReader(responseStream, this._knownTypes); // Read the response while (this._syncReader.Next()) { switch (this._syncReader.ItemType) { case ReaderItemType.Entry: IOfflineEntity entity = this._syncReader.GetItem(); IOfflineEntity ackedEntity = entity; string tempId = null; // If conflict only one temp ID should be set if (this._syncReader.HasTempId() && this._syncReader.HasConflictTempId()) { throw new CacheControllerException(string.Format("Service returned a TempId '{0}' in both live and conflicting entities.", this._syncReader.GetTempId())); } // Validate the live temp ID if any, before adding anything to the offline context if (this._syncReader.HasTempId()) { tempId = this._syncReader.GetTempId(); CheckEntityServiceMetadataAndTempIds(wrapper, entity, tempId); } // If conflict if (this._syncReader.HasConflict()) { Conflict conflict = this._syncReader.GetConflict(); IOfflineEntity conflictEntity = (conflict is SyncConflict) ? ((SyncConflict)conflict).LosingEntity : ((SyncError)conflict).ErrorEntity; // Validate conflict temp ID if any if (this._syncReader.HasConflictTempId()) { tempId = this._syncReader.GetConflictTempId(); CheckEntityServiceMetadataAndTempIds(wrapper, conflictEntity, tempId); } // Add conflict wrapper.UploadResponse.AddConflict(conflict); // // If there is a conflict and the tempId is set in the conflict entity then the client version lost the // conflict and the live entity is the server version (ServerWins) // if (this._syncReader.HasConflictTempId() && entity.ServiceMetadata.IsTombstone) { // // This is a ServerWins conflict, or conflict error. The winning version is a tombstone without temp Id // so there is no way to map the winning entity with a temp Id. The temp Id is in the conflict so we are // using the conflict entity, which has the PK, to build a tombstone entity used to update the offline context // // In theory, we should copy the service metadata but it is the same end result as the service fills in // all the properties in the conflict entity // // Add the conflict entity conflictEntity.ServiceMetadata.IsTombstone = true; ackedEntity = conflictEntity; } } // Add ackedEntity to storage. If ackedEntity is still equal to entity then add non-conflict entity. if (!String.IsNullOrEmpty(tempId)) { wrapper.UploadResponse.AddUpdatedItem(ackedEntity); } break; case ReaderItemType.SyncBlob: wrapper.UploadResponse.ServerBlob = this._syncReader.GetServerBlob(); break; } } if (wrapper.TempIdToEntityMapping != null && wrapper.TempIdToEntityMapping.Count != 0) { // The client sent some inserts which werent ack'd by the service. Throw. StringBuilder builder = new StringBuilder("Server did not acknowledge with a permanent Id for the following tempId's: "); builder.Append(string.Join(",", wrapper.TempIdToEntityMapping.Keys.ToArray())); throw new CacheControllerException(builder.ToString()); } wrapper.WebResponse = response; // Invoke user code on the correct synchronization context. this.FirePostResponseHandler(wrapper); } else { wrapper.UploadResponse.Error = new CacheControllerException( string.Format("Remote service returned error status. Status: {0}, Description: {1}", response.StatusCode, response.StatusDescription)); } // If we get here then it means we completed the request. Return to the original caller this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper); } catch (Exception e) { if (ExceptionUtility.IsFatal(e)) { throw; } wrapper.Error = e; this._workerManager.CompleteWorkRequest(wrapper.WorkerRequest, wrapper); } }
void OnDownloadCompleted(object sender, NSUrlEventArgs e) { FileStream fileStream = null; string filePath = null; try { if (e.Error == null) { filePath = e.FilePath.Replace("file://", "").Replace("%20", " "); NSHttpUrlResponse response = (NSHttpUrlResponse)_currentTask.Response; if (response != null) { HttpStatusCode code = (HttpStatusCode)response.StatusCode; if (code == HttpStatusCode.OK) { NSDictionary headers = response.AllHeaderFields; if (string.IsNullOrWhiteSpace(_behaviors.UserId)) { _behaviors.UserId = headers ["userid"].ToString(); } if (string.IsNullOrWhiteSpace(_behaviors.UserEmail)) { _behaviors.UserEmail = headers ["email"].ToString(); } ; _behaviors.SaveUserSession(); if (File.Exists(filePath)) { fileStream = File.OpenRead(filePath); fileStream.Seek(0, SeekOrigin.Begin); int contentLength; if (!int.TryParse(headers ["unzippedcontentlength"].ToString(), out contentLength)) { contentLength = -1; } Stream responseStream = new ProgressStream(fileStream, contentLength, _behaviors.ReadProgressCallback); // Create the SyncReader _syncReader = (SyncReader) new ODataAtomReader(responseStream, _knownTypes); _wrapper.DownloadResponse = new ChangeSet(); // Read the response while (this._syncReader.Next()) { switch (this._syncReader.ItemType) { case ReaderItemType.Entry: _wrapper.DownloadResponse.AddItem(_syncReader.GetItem()); break; case ReaderItemType.SyncBlob: _wrapper.DownloadResponse.ServerBlob = _syncReader.GetServerBlob(); break; case ReaderItemType.HasMoreChanges: _wrapper.DownloadResponse.IsLastBatch = !_syncReader.GetHasMoreChangesValue(); break; } } } else { _wrapper.Error = new FileNotFoundException(String.Format("Downloaded data file not found! {0}, Description: {1}", e.FilePath, response.Description)); } } else { _wrapper.Error = new CacheControllerWebException(string.Format("Remote service returned error status. Status: {0}, Description: {1}", code, response.Description), code); } } else { _wrapper.Error = new CacheControllerException("Response is null"); } } else { NSHttpUrlResponse response = _currentTask.Response as NSHttpUrlResponse; HandleError(e.Error, response); } // If we get here then it means we completed the request. Return to the original caller _workerManager.CompleteWorkRequest(_wrapper.WorkerRequest, _wrapper); } catch (Exception ex) { if (ExceptionUtility.IsFatal(ex)) { throw; } _wrapper.Error = ex; _workerManager.CompleteWorkRequest(_wrapper.WorkerRequest, _wrapper); } finally { if (fileStream != null) { fileStream.Close(); } if (filePath != null && File.Exists(filePath)) { File.Delete(filePath); } } }
void OnUploadCompleted(object sender, NSUrlEventArgs e) { _wrapper.UploadResponse = new ChangeSetResponse(); FileStream fileStream = null; string filePath = null; try { if (e.Error == null) { string responseDescription = "response is null"; NSHttpUrlResponse response = (NSHttpUrlResponse)_currentTask.Response; if (response != null) { responseDescription = response.Description; } filePath = e.FilePath.Replace("file://", "").Replace("%20", " "); if (File.Exists(filePath)) { fileStream = File.OpenRead(filePath); fileStream.Seek(0, SeekOrigin.Begin); // Create the SyncReader _syncReader = (SyncReader) new ODataAtomReader(fileStream, _knownTypes); // Read the response while (_syncReader.Next()) { switch (_syncReader.ItemType) { case ReaderItemType.Entry: IOfflineEntity entity = _syncReader.GetItem(); IOfflineEntity ackedEntity = entity; string tempId = null; if (_syncReader.HasTempId() && _syncReader.HasConflictTempId()) { throw new CacheControllerException(string.Format("Service returned a TempId '{0}' in both live and conflicting entities.", _syncReader.GetTempId())); } if (_syncReader.HasTempId()) { tempId = _syncReader.GetTempId(); CheckEntityServiceMetadataAndTempIds(entity, tempId); } if (_syncReader.HasConflict()) { Conflict conflict = _syncReader.GetConflict(); IOfflineEntity conflictEntity = (conflict is SyncConflict) ? ((SyncConflict)conflict).LosingEntity : ((SyncError)conflict).ErrorEntity; if (this._syncReader.HasConflictTempId()) { tempId = _syncReader.GetConflictTempId(); CheckEntityServiceMetadataAndTempIds(conflictEntity, tempId); } _wrapper.UploadResponse.AddConflict(conflict); if (_syncReader.HasConflictTempId() && entity.ServiceMetadata.IsTombstone) { conflictEntity.ServiceMetadata.IsTombstone = true; ackedEntity = conflictEntity; } } if (!String.IsNullOrEmpty(tempId)) { _wrapper.UploadResponse.AddUpdatedItem(ackedEntity); } break; case ReaderItemType.SyncBlob: _wrapper.UploadResponse.ServerBlob = _syncReader.GetServerBlob(); break; } } if (_wrapper.TempIdToEntityMapping != null && _wrapper.TempIdToEntityMapping.Count != 0) { StringBuilder builder = new StringBuilder("Server did not acknowledge with a permanent Id for the following tempId's: "); builder.Append(string.Join(",", _wrapper.TempIdToEntityMapping.Keys.ToArray())); throw new CacheControllerException(builder.ToString()); } } else { _wrapper.Error = new FileNotFoundException(String.Format("Downloaded data file not found! {0}, Description: {1}", e.FilePath, responseDescription)); } } else { NSHttpUrlResponse response = _currentTask.Response as NSHttpUrlResponse; HandleError(e.Error, response); } _workerManager.CompleteWorkRequest(_wrapper.WorkerRequest, _wrapper); } catch (Exception ex) { if (ExceptionUtility.IsFatal(ex)) { throw ex; } _wrapper.Error = ex; _workerManager.CompleteWorkRequest(_wrapper.WorkerRequest, _wrapper); } finally { if (fileStream != null) { fileStream.Close(); } if (filePath != null && File.Exists(filePath)) { File.Delete(filePath); } } }
/// <summary> /// Callback for the Upload HttpWebRequest.BeginGetResponse call /// </summary> private async Task ReadUploadResponse(HttpWebResponse response, AsyncArgsWrapper wrapper) { try { if (response.StatusCode == HttpStatusCode.OK) { Stream responseStream = response.GetResponseStream(); this.syncReader = (SerializationFormat == SerializationFormat.ODataAtom) ? new ODataAtomReader(responseStream, this.knownTypes) : (SyncReader) new ODataJsonReader(responseStream, this.knownTypes); // Read the response await Task.Factory.StartNew(() => { while (syncReader.Next()) { switch (syncReader.ItemType) { case ReaderItemType.Entry: IOfflineEntity entity = syncReader.GetItem(); IOfflineEntity ackedEntity = entity; string tempId = null; // If conflict only one temp ID should be set if (syncReader.HasTempId() && syncReader.HasConflictTempId()) { throw new CacheControllerException( string.Format( "Service returned a TempId '{0}' in both live and conflicting entities.", syncReader.GetTempId())); } // Validate the live temp ID if any, before adding anything to the offline context if (syncReader.HasTempId()) { tempId = syncReader.GetTempId(); CheckEntityServiceMetadataAndTempIds(wrapper, entity, tempId); } // If conflict if (syncReader.HasConflict()) { Conflict conflict = syncReader.GetConflict(); IOfflineEntity conflictEntity = (conflict is SyncConflict) ? ((SyncConflict)conflict).LosingEntity : ((SyncError)conflict).ErrorEntity; // Validate conflict temp ID if any if (syncReader.HasConflictTempId()) { tempId = syncReader.GetConflictTempId(); CheckEntityServiceMetadataAndTempIds(wrapper, conflictEntity, tempId); } // Add conflict wrapper.UploadResponse.AddConflict(conflict); // // If there is a conflict and the tempId is set in the conflict entity then the client version lost the // conflict and the live entity is the server version (ServerWins) // if (syncReader.HasConflictTempId() && entity.GetServiceMetadata().IsTombstone) { // // This is a ServerWins conflict, or conflict error. The winning version is a tombstone without temp Id // so there is no way to map the winning entity with a temp Id. The temp Id is in the conflict so we are // using the conflict entity, which has the PK, to build a tombstone entity used to update the offline context // // In theory, we should copy the service metadata but it is the same end result as the service fills in // all the properties in the conflict entity // // Add the conflict entity conflictEntity.GetServiceMetadata().IsTombstone = true; ackedEntity = conflictEntity; } } // Add ackedEntity to storage. If ackedEntity is still equal to entity then add non-conflict entity. if (!String.IsNullOrEmpty(tempId)) { wrapper.UploadResponse.AddUpdatedItem(ackedEntity); } break; case ReaderItemType.SyncBlob: wrapper.UploadResponse.ServerBlob = syncReader.GetServerBlob(); break; } } }); if (wrapper.TempIdToEntityMapping != null && wrapper.TempIdToEntityMapping.Count != 0) { // The client sent some inserts which werent ack'd by the service. Throw. var builder = new StringBuilder( "Server did not acknowledge with a permanent Id for the following tempId's: "); builder.Append(string.Join(",", wrapper.TempIdToEntityMapping.Keys.ToArray())); throw new CacheControllerException(builder.ToString()); } } else { wrapper.UploadResponse.Error = new CacheControllerException( string.Format("Remote service returned error status. Status: {0}, Description: {1}", response.StatusCode, response.StatusDescription)); } } catch (Exception e) { if (ExceptionUtility.IsFatal(e)) { throw; } wrapper.Error = e; } }
void OnDownloadCompleted(object sender, NSUrlEventArgs e) { try { if (e.Error == null) { _filePath = e.FilePath.Replace("file://", "").Replace("%20", " "); NSHttpUrlResponse response = (NSHttpUrlResponse)_currentTask.Response; if (response != null) { HttpStatusCode code = (HttpStatusCode)response.StatusCode; if (code == HttpStatusCode.OK) { NSDictionary headers = response.AllHeaderFields; if (string.IsNullOrWhiteSpace(_behaviors.UserId)) { _behaviors.UserId = headers["userid"].ToString(); } if (string.IsNullOrWhiteSpace(_behaviors.UserEmail)) { _behaviors.UserEmail = headers["email"].ToString(); } _behaviors.ResourceVersion = headers["resourceversion"].ToString(); _behaviors.SaveUserSession(); IIOContext io = IOContext.Current; if (io.Exists(_filePath)) { FileStream fileStream = io.FileStream(_filePath, FileMode.Open); fileStream.Seek(0, SeekOrigin.Begin); int contentLength; if (!int.TryParse(headers["unzippedcontentlength"].ToString(), out contentLength)) { contentLength = -1; } Stream responseStream = new ProgressStream(fileStream, contentLength, _behaviors.ReadProgressCallback); // CreateInstance the SyncReader if (ApplicationContext.Current.Settings.BitMobileFormatterDisabled) { _syncReader = new ODataAtomReader(responseStream, _knownTypes); } else { _syncReader = new BMReader(responseStream, _knownTypes); } _wrapper.DownloadResponse = new ChangeSet(); _wrapper.DownloadResponse.Data = GetDownloadedValues(_wrapper); } else { _wrapper.Error = new FileNotFoundException(String.Format("Downloaded data file not found! {0}, Description: {1}", e.FilePath, response.Description)); } } else { _wrapper.Error = new CacheControllerWebException(string.Format("Remote service returned error status. Status: {0}, Description: {1}", code, response.Description), code); } } else { _wrapper.Error = new CacheControllerException("Response is null"); } } else { var response = _currentTask.Response as NSHttpUrlResponse; HandleError(e.Error, response); } // If we get here then it means we completed the request. Return to the original caller _workerManager.CompleteWorkRequest(_wrapper.WorkerRequest, _wrapper); } catch (Exception ex) { if (ExceptionUtility.IsFatal(ex)) { throw; } _wrapper.Error = ex; _workerManager.CompleteWorkRequest(_wrapper.WorkerRequest, _wrapper); } }
void OnUploadCompleted(object sender, NSUrlEventArgs e) { _wrapper.UploadResponse = new ChangeSetResponse(); FileStream fileStream = null; string filePath = null; try { if (e.Error == null) { string responseDescription = "response is null"; var response = (NSHttpUrlResponse)_currentTask.Response; if (response != null) { responseDescription = response.Description; } filePath = e.FilePath.Replace("file://", "").Replace("%20", " "); IIOContext io = IOContext.Current; if (io.Exists(filePath)) { fileStream = io.FileStream(filePath, FileMode.Open); fileStream.Seek(0, SeekOrigin.Begin); // CreateInstance the SyncReader if (ApplicationContext.Current.Settings.BitMobileFormatterDisabled) { _syncReader = new ODataAtomReader(fileStream, _knownTypes); } else { _syncReader = new BMReader(fileStream, _knownTypes); } // Read the response while (_syncReader.Next()) { switch (_syncReader.ItemType) { case ReaderItemType.Entry: IOfflineEntity entity = _syncReader.GetItem(); IOfflineEntity ackedEntity = entity; string tempId = null; if (_syncReader.HasTempId() && _syncReader.HasConflictTempId()) { throw new CacheControllerException(string.Format("Service returned a TempId '{0}' in both live and conflicting entities.", _syncReader.GetTempId())); } if (_syncReader.HasTempId()) { tempId = _syncReader.GetTempId(); CheckEntityServiceMetadataAndTempIds(entity, tempId); } if (_syncReader.HasConflict()) { Conflict conflict = _syncReader.GetConflict(); IOfflineEntity conflictEntity = (conflict is SyncConflict) ? ((SyncConflict)conflict).LosingEntity : ((SyncError)conflict).ErrorEntity; if (_syncReader.HasConflictTempId()) { tempId = _syncReader.GetConflictTempId(); CheckEntityServiceMetadataAndTempIds(conflictEntity, tempId); } _wrapper.UploadResponse.AddConflict(conflict); if (_syncReader.HasConflictTempId() && entity.ServiceMetadata.IsTombstone) { conflictEntity.ServiceMetadata.IsTombstone = true; ackedEntity = conflictEntity; } } if (!String.IsNullOrEmpty(tempId)) { _wrapper.UploadResponse.AddUpdatedItem(ackedEntity); } break; case ReaderItemType.SyncBlob: _wrapper.UploadResponse.ServerBlob = _syncReader.GetServerBlob(); break; } } } else { _wrapper.Error = new FileNotFoundException(String.Format("Downloaded data file not found! {0}, Description: {1}", e.FilePath, responseDescription)); } } else { var response = _currentTask.Response as NSHttpUrlResponse; HandleError(e.Error, response); } _workerManager.CompleteWorkRequest(_wrapper.WorkerRequest, _wrapper); } catch (Exception ex) { if (ExceptionUtility.IsFatal(ex)) { throw; } _wrapper.Error = ex; _workerManager.CompleteWorkRequest(_wrapper.WorkerRequest, _wrapper); } finally { if (fileStream != null) { fileStream.Close(); } if (filePath != null) { IOContext.Current.Delete(filePath); } } }