Exemplo n.º 1
0
        /// <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(null != context, "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,
                "Only get and post 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*/);

            QueryResult queryResult = null;

            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);
                serializer.WriteBodyOperationParameters(qc.BodyOperationParameters, requestMessage);

                // pass in the request stream so that request payload can be written to the http webrequest.
                queryResult = new QueryResult(source, method, this, requestMessage, requestInfo, callback, state, requestMessage.CachedRequestStream);
            }
            else
            {
                queryResult = new QueryResult(source, method, this, requestMessage, requestInfo, callback, state);
            }

            return(queryResult);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Fire SendingRequest event if its conditions are met.
        /// If the user has a handler for BuildingRequest, we will throw.
        /// If the user has no BuildingRequest handlers but does have a SendingRequest2 handler, we silently do not fire this event (this is shipped 5.0 behavior).
        /// </summary>
        private void FireSendingRequest()
        {
            // Do not fire SendingRequest event when user tries to wrap the HttpWebRequestMessage
            if (this.fireSendingRequestMethodCalled || this.requestInfo == null)
            {
                return;
            }

            // We need to set this before SendingRequest event is fired so that
            // GetStream method can throw if it is called from SendingRequest event.
            this.fireSendingRequestMethodCalled = true;

            HeaderCollection cachedHeaders = null;

            if (this.requestInfo.HasSendingRequestEventHandlers)
            {
                // Before firing SendingRequest event, we need to cache all the header values so that
                // we can reset them to the original values after SendingRequest event has been fired.
                cachedHeaders = new HeaderCollection();
                foreach (var header in this.Headers)
                {
                    cachedHeaders.SetHeader(header.Key, header.Value);
                }
#if PORTABLELIB
                cachedHeaders.SetHeader(XmlConstants.HttpContentLength, this.httpRequest.Headers[XmlConstants.HttpContentLength]);
#endif
#if !ASTORIA_LIGHT && !PORTABLELIB
                // Content-Length and accept header does not show up in the header collection at all.
                // Hence adding it explicitly, since we reset the content length header
                // after firing SendingRequest event
                cachedHeaders.SetHeader(XmlConstants.HttpContentLength, this.httpRequest.ContentLength.ToString(CultureInfo.InvariantCulture));
#endif
            }

            // Fires whenever a new HttpWebRequest has been created
            // The event fires early - before the client library sets many of its required property values.
            // This ensures the client library has the last say on the value of mandated properties
            // such as the HTTP verb  being used for the request.
            if (this.requestInfo.HasSendingRequestEventHandlers)
            {
                System.Net.WebHeaderCollection requestHeaders;
#if !ASTORIA_LIGHT
                requestHeaders = this.httpRequest.Headers;
                SendingRequestEventArgs args = new SendingRequestEventArgs(this.httpRequest, requestHeaders);
#else
                requestHeaders = this.httpRequest.CreateEmptyWebHeaderCollection();
                /* Also set header for SL, MaxDataServcieVersion is required header */
                foreach (var head in this.Headers)
                {
                    if (head.Key == XmlConstants.HttpMaxDataServiceVersion)
                    {
                        requestHeaders[XmlConstants.HttpMaxDataServiceVersion] = head.Value;
                        break;
                    }
                }

                SendingRequestEventArgs args = new SendingRequestEventArgs(null, requestHeaders);
#endif
                this.requestInfo.FireSendingRequest(args);

#if !ASTORIA_LIGHT
                if (!Object.ReferenceEquals(args.Request, this.httpRequest))
                {
                    this.httpRequest = (System.Net.HttpWebRequest)args.Request;
                }
#else
                // apply all headers to the request
                foreach (string key in requestHeaders.AllKeys)
                {
                    this.httpRequest.Headers[key] = requestHeaders[key];
                }
#endif
                HttpWebRequestMessage.SetHeaderValues(this, cachedHeaders, this.Method);
            }
        }