/// <summary> /// Get all items by auto iterating all pages, will send the request of first page as default, regardless if it's iterated. /// </summary> /// <returns>The items retrieved</returns> public IEnumerable <TElement> GetAllPages() { QueryOperationResponse <TElement> response = this.Execute <TElement>(this.Context, this.Translate()); return(this.GetRestPages(response)); }
/// <summary> /// process the batch response /// </summary> /// <param name="batchReader">The batch reader to use for reading the batch response.</param> /// <returns>enumerable of QueryResponse or null</returns> /// <remarks> /// The batch message reader for the entire batch response is stored in this.batchMessageReader. /// Note that this method takes over the ownership of this reader and must Dispose it if it successfully returns. /// </remarks> private IEnumerable <OperationResponse> HandleBatchResponse(ODataBatchReader batchReader) { try { if (this.batchMessageReader == null) { // The enumerable returned by this method can be enumerated multiple times. // In that case it looks like if the method is called multiple times. // This didn't fail in previous versions, it simply returned no results, so we need to do the same. yield break; } Debug.Assert(batchReader != null, "batchReader != null"); bool changesetFound = false; bool insideChangeset = false; int queryCount = 0; int operationCount = 0; this.entryIndex = 0; while (batchReader.Read()) { switch (batchReader.State) { #region ChangesetStart case ODataBatchReaderState.ChangesetStart: if ((Util.IsBatchWithSingleChangeset(this.Options) && changesetFound) || (operationCount != 0)) { // Throw if we encounter multiple changesets when running in batch with single changeset mode // or if we encounter operations outside of a changeset. Error.ThrowBatchUnexpectedContent(InternalError.UnexpectedBeginChangeSet); } insideChangeset = true; break; #endregion #region ChangesetEnd case ODataBatchReaderState.ChangesetEnd: changesetFound = true; operationCount = 0; insideChangeset = false; break; #endregion #region Operation case ODataBatchReaderState.Operation: Exception exception = this.ProcessCurrentOperationResponse(batchReader, insideChangeset); if (!insideChangeset) { #region Get response Debug.Assert(operationCount == 0, "missing an EndChangeSet 2"); QueryOperationResponse qresponse = null; try { if (exception == null) { DataServiceRequest query = this.Queries[queryCount]; ResponseInfo responseInfo = this.RequestInfo.GetDeserializationInfo(null /*mergeOption*/); MaterializeAtom materializer = DataServiceRequest.Materialize( responseInfo, query.QueryComponents(this.RequestInfo.Model), null, this.currentOperationResponse.Headers.GetHeader(XmlConstants.HttpContentType), this.currentOperationResponse.CreateResponseMessage(), query.PayloadKind); qresponse = QueryOperationResponse.GetInstance(query.ElementType, this.currentOperationResponse.Headers, query, materializer); } } catch (ArgumentException e) { exception = e; } catch (FormatException e) { exception = e; } catch (InvalidOperationException e) { exception = e; } if (qresponse == null) { if (this.Queries != null) { // this is the normal ExecuteBatch response DataServiceRequest query = this.Queries[queryCount]; if (this.RequestInfo.IgnoreResourceNotFoundException && this.currentOperationResponse.StatusCode == HttpStatusCode.NotFound) { qresponse = QueryOperationResponse.GetInstance(query.ElementType, this.currentOperationResponse.Headers, query, MaterializeAtom.EmptyResults); } else { qresponse = QueryOperationResponse.GetInstance(query.ElementType, this.currentOperationResponse.Headers, query, MaterializeAtom.EmptyResults); qresponse.Error = exception; } } else { // This is top-level failure for SaveChanges(SaveChangesOptions.BatchWithSingleChangeset) or SaveChanges(SaveChangesOptions.BatchWithIndependentOperations) operations. // example: server doesn't support batching or number of batch objects exceeded an allowed limit. // ex could be null if the server responded to SaveChanges with an unexpected success with // response of batched GETS that did not correspond the original POST/PATCH/PUT/DELETE requests. // we expect non-null since server should have failed with a non-success code // and HandleResponse(status, ...) should generate the exception object throw exception; } } qresponse.StatusCode = (int)this.currentOperationResponse.StatusCode; queryCount++; yield return(qresponse); #endregion } else { #region Update response try { Descriptor descriptor = this.ChangedEntries[this.entryIndex]; operationCount += this.SaveResultProcessed(descriptor); if (exception != null) { throw exception; } this.HandleOperationResponseHeaders(this.currentOperationResponse.StatusCode, this.currentOperationResponse.Headers); #if DEBUG this.HandleOperationResponse(descriptor, this.currentOperationResponse.Headers, this.currentOperationResponse.StatusCode); #else this.HandleOperationResponse(descriptor, this.currentOperationResponse.Headers); #endif } catch (Exception e) { this.ChangedEntries[this.entryIndex].SaveError = e; exception = e; if (!CommonUtil.IsCatchableExceptionType(e)) { throw; } } ChangeOperationResponse changeOperationResponse = new ChangeOperationResponse(this.currentOperationResponse.Headers, this.ChangedEntries[this.entryIndex]); changeOperationResponse.StatusCode = (int)this.currentOperationResponse.StatusCode; if (exception != null) { changeOperationResponse.Error = exception; } operationCount++; this.entryIndex++; yield return(changeOperationResponse); #endregion } break; #endregion default: Error.ThrowBatchExpectedResponse(InternalError.UnexpectedBatchState); break; } } Debug.Assert(batchReader.State == ODataBatchReaderState.Completed, "unexpected batch state"); // Check for a changeset without response (first line) or GET request without response (second line). // either all saved entries must be processed or it was a batch and one of the entries has the error if ((this.Queries == null && (!changesetFound || 0 < queryCount || this.ChangedEntries.Any(o => o.ContentGeneratedForSave && o.SaveResultWasProcessed == 0) && (!this.IsBatchRequest || this.ChangedEntries.FirstOrDefault(o => o.SaveError != null) == null))) || (this.Queries != null && queryCount != this.Queries.Length)) { throw Error.InvalidOperation(Strings.Batch_IncompleteResponseCount); } } finally { // Note that this will be called only once the enumeration of all responses is finished and the Dispose // was called on the IEnumerator used for that enumeration. It is not called when the method returns, // since the compiler change this method to return the compiler-generated IEnumerable. Util.Dispose(ref this.batchMessageReader); } }
/// <summary>Initializes a new instance of the <see cref="Microsoft.OData.Client.DataServiceQueryException" /> class. </summary> /// <param name="message">The string value that contains the error message.</param> /// <param name="innerException">The inner exception object.</param> /// <param name="response">The <see cref="Microsoft.OData.Client.QueryOperationResponse" /> object.</param> public DataServiceQueryException(string message, Exception innerException, QueryOperationResponse response) : base(message, innerException) { this.response = response; }
/// <summary>Constructor</summary> /// <param name="queryOperationResponse">The response for the Load operation. null when the operation didn't succeed.</param> /// <param name="error"><see cref="Exception"/> which represents the error if the Load operation failed. null if the operation /// didn't fail.</param> /// <remarks>This constructor doesn't allow creation of canceled event args.</remarks> internal LoadCompletedEventArgs(QueryOperationResponse queryOperationResponse, Exception error) : this(queryOperationResponse, error, false) { }
public QueryOperationResponseWrapper(QueryOperationResponse qr) : base(qr) { this._QueryResponse = qr; }
/// <summary> /// Synchronizely get the query set count from the server by executing the $count=value query /// </summary> /// <param name="context">The context</param> /// <returns>The server side count of the query set</returns> internal long GetQuerySetCount(DataServiceContext context) { Debug.Assert(null != context, "context is null"); Version requestVersion = this.QueryComponents(context.Model).Version; if (requestVersion == null) { requestVersion = Util.ODataVersion4; } QueryResult response = null; QueryComponents qc = this.QueryComponents(context.Model); Uri requestUri = qc.Uri; DataServiceRequest <long> serviceRequest = new DataServiceRequest <long>(requestUri, qc, null); HeaderCollection headers = new HeaderCollection(); // Validate and set the request DSV header headers.SetRequestVersion(requestVersion, context.MaxProtocolVersionAsVersion); context.Format.SetRequestAcceptHeaderForCount(headers); string httpMethod = XmlConstants.HttpMethodGet; ODataRequestMessageWrapper request = context.CreateODataRequestMessage( context.CreateRequestArgsAndFireBuildingRequest(httpMethod, requestUri, headers, context.HttpStack, null /*descriptor*/), null /*descriptor*/); response = new QueryResult(this, Util.ExecuteMethodName, serviceRequest, request, new RequestInfo(context), null, null); try { response.ExecuteQuery(); if (HttpStatusCode.NoContent != response.StatusCode) { StreamReader sr = new StreamReader(response.GetResponseStream()); long r = -1; try { r = XmlConvert.ToInt64(sr.ReadToEnd()); } finally { sr.Close(); } return(r); } else { throw new DataServiceQueryException(Strings.DataServiceRequest_FailGetCount, response.Failure); } } catch (InvalidOperationException ex) { QueryOperationResponse operationResponse = null; operationResponse = response.GetResponse <long>(MaterializeAtom.EmptyResults); if (null != operationResponse) { operationResponse.Error = ex; throw new DataServiceQueryException(Strings.DataServiceException_GeneralError, ex, operationResponse); } throw; } }