/// <summary> /// Creates the result object for the specified query parameters. /// </summary> /// <param name="source">The source object for the request.</param> /// <param name="context">The data service context.</param> /// <param name="callback">The AsyncCallback delegate.</param> /// <param name="state">The state object for the callback.</param> /// <param name="method">async method name at the source.</param> /// <returns>Result representing the create request. The request has not been initiated yet.</returns> private QueryResult CreateExecuteResult(object source, DataServiceContext context, AsyncCallback callback, object state, string method) { Debug.Assert(context != null, "context is null"); QueryComponents qc = this.QueryComponents(context.Model); RequestInfo requestInfo = new RequestInfo(context); Debug.Assert( string.CompareOrdinal(XmlConstants.HttpMethodPost, qc.HttpMethod) == 0 || string.CompareOrdinal(XmlConstants.HttpMethodGet, qc.HttpMethod) == 0 || string.CompareOrdinal(XmlConstants.HttpMethodDelete, qc.HttpMethod) == 0, "Only get, post and delete are supported in the execute pipeline, which should have been caught earlier"); if (qc.UriOperationParameters != null) { Debug.Assert(qc.UriOperationParameters.Any(), "qc.UriOperationParameters.Any()"); Serializer serializer = new Serializer(requestInfo); this.RequestUri = serializer.WriteUriOperationParametersToUri(this.RequestUri, qc.UriOperationParameters); } HeaderCollection headers = new HeaderCollection(); if (string.CompareOrdinal(XmlConstants.HttpMethodPost, qc.HttpMethod) == 0) { if (qc.BodyOperationParameters == null) { // set the content length to be 0 if there are no operation parameters. headers.SetHeader(XmlConstants.HttpContentLength, "0"); } else { context.Format.SetRequestContentTypeForOperationParameters(headers); } } // Validate and set the request DSV and MDSV header headers.SetRequestVersion(qc.Version, requestInfo.MaxProtocolVersionAsVersion); requestInfo.Format.SetRequestAcceptHeaderForQuery(headers, qc); // We currently do not have a descriptor to expose to the user for invoking something through Execute. Ideally we could expose an OperationDescriptor. ODataRequestMessageWrapper requestMessage = new RequestInfo(context).WriteHelper.CreateRequestMessage(context.CreateRequestArgsAndFireBuildingRequest(qc.HttpMethod, this.RequestUri, headers, context.HttpStack, null /*descriptor*/)); requestMessage.FireSendingRequest2(null /*descriptor*/); if (qc.BodyOperationParameters != null) { Debug.Assert(string.CompareOrdinal(XmlConstants.HttpMethodPost, qc.HttpMethod) == 0, "qc.HttpMethod == XmlConstants.HttpMethodPost"); Debug.Assert(qc.BodyOperationParameters.Any(), "unexpected body operation parameter count of zero."); Serializer serializer = new Serializer(requestInfo, context.EntityParameterSendOption); serializer.WriteBodyOperationParameters(qc.BodyOperationParameters, requestMessage); // pass in the request stream so that request payload can be written to the http webrequest. return(new QueryResult(source, method, this, requestMessage, requestInfo, callback, state, requestMessage.CachedRequestStream)); } return(new QueryResult(source, method, this, requestMessage, requestInfo, callback, state)); }
/// <summary> /// Loads the metadata and converts it into an EdmModel that is then used by a dataservice context /// This allows the user to use the DataServiceContext directly without having to manually pass an IEdmModel in the Format /// </summary> /// <returns>A service model to be used in format tracking</returns> internal IEdmModel LoadServiceModelFromNetwork() { HttpWebRequestMessage httpRequest; BuildingRequestEventArgs requestEventArgs = null; // test hook for injecting a network request to use instead of the default if (InjectMetadataHttpNetworkRequest != null) { httpRequest = InjectMetadataHttpNetworkRequest(); } else { requestEventArgs = new BuildingRequestEventArgs( "GET", context.GetMetadataUri(), null, null, context.HttpStack); // fire the right events if they exist to allow user to modify the request if (context.HasBuildingRequestEventHandlers) { requestEventArgs = context.CreateRequestArgsAndFireBuildingRequest( requestEventArgs.Method, requestEventArgs.RequestUri, requestEventArgs.HeaderCollection, requestEventArgs.ClientHttpStack, requestEventArgs.Descriptor); } DataServiceClientRequestMessageArgs args = new DataServiceClientRequestMessageArgs( requestEventArgs.Method, requestEventArgs.RequestUri, context.UseDefaultCredentials, context.UsePostTunneling, requestEventArgs.Headers); httpRequest = new HttpWebRequestMessage(args); } Descriptor descriptor = requestEventArgs != null ? requestEventArgs.Descriptor : null; // fire the right events if they exist if (context.HasSendingRequest2EventHandlers) { SendingRequest2EventArgs eventArgs = new SendingRequest2EventArgs( httpRequest, descriptor, false); context.FireSendingRequest2(eventArgs); } Task <IODataResponseMessage> asyncResponse = Task <IODataResponseMessage> .Factory.FromAsync(httpRequest.BeginGetResponse, httpRequest.EndGetResponse, httpRequest); IODataResponseMessage response = asyncResponse.GetAwaiter().GetResult(); ReceivingResponseEventArgs responseEvent = new ReceivingResponseEventArgs(response, descriptor); context.FireReceivingResponseEvent(responseEvent); using (StreamReader streamReader = new StreamReader(response.GetStream())) using (XmlReader xmlReader = XmlReader.Create(streamReader)) { return(CsdlReader.Parse(xmlReader)); } }
/// <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; } }