/// <summary>
        /// Initializes a new dummy host for the batch request.
        /// This host represents a single operation in the batch.
        /// </summary>
        /// <param name="absoluteServiceUri">Absolute Uri to the service.</param>
        /// <param name="operationMessage">The request message representing a batch operation to wrap.</param>
        /// <param name="contentId">Content id for the given operation host.</param>
        /// <param name="writer">ODataBatchWriter instance.</param>
        /// <param name="odataMaxVersion">OData-MaxVersion header on the batch request. If the OData-MaxVersion header is not specified in the current operation, we default to the MaxDSV from the batch level.</param>
        internal BatchServiceHost(Uri absoluteServiceUri, IODataRequestMessage operationMessage, string contentId, ODataBatchWriter writer, Version odataMaxVersion)
            : this(writer)
        {
            Debug.Assert(absoluteServiceUri != null && absoluteServiceUri.IsAbsoluteUri, "absoluteServiceUri != null && absoluteServiceUri.IsAbsoluteUri");
            Debug.Assert(operationMessage != null, "operationMessage != null");
            this.absoluteServiceUri = absoluteServiceUri;
            this.absoluteRequestUri = RequestUriProcessor.GetAbsoluteUriFromReference(operationMessage.Url, absoluteServiceUri);

            this.requestHttpMethod = operationMessage.Method;
            this.contentId = contentId;

            foreach (KeyValuePair<string, string> header in operationMessage.Headers)
            {
                this.requestHeaders.Add(header.Key, header.Value);
            }

            // If the MaxDSV header is not specified in the current operation, we default to the MaxDSV from the batch level.
            if (string.IsNullOrEmpty(this.requestHeaders[XmlConstants.HttpODataMaxVersion]))
            {
                Debug.Assert(odataMaxVersion != null, "odataMaxVersion != null");
                this.requestHeaders[XmlConstants.HttpODataMaxVersion] = odataMaxVersion.ToString();
            }

            this.requestStream = operationMessage.GetStream();
        }
        /// <summary>
        /// Constructs an internal wrapper around the <paramref name="requestMessage"/>
        /// that isolates the internal implementation of the ODataLib from the interface.
        /// </summary>
        /// <param name="requestMessage">The request message to wrap.</param>
        internal ODataRequestMessage(IODataRequestMessage requestMessage)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(requestMessage != null, "requestMessage != null");

            this.requestMessage = requestMessage;
        }
Exemple #3
0
        private void ProcessUpdateEntityReference(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage, ODataPath odataPath)
        {
            // This is for change the reference in single-valued navigation property
            // PUT ~/Person(0)/Parent/$ref
            // {
            //     "@odata.context": "http://host/service/$metadata#$ref",
            //     "@odata.id": "Orders(10643)"
            // }

            if (this.HttpMethod == HttpMethod.PATCH)
            {
                throw Utility.BuildException(HttpStatusCode.MethodNotAllowed, "PATCH on a reference link is not supported.", null);
            }

            // Get the parent first
            var level = this.QueryContext.QueryPath.Count - 2;
            var parent = this.QueryContext.ResolveQuery(this.DataSource, level);

            var navigationPropertyName = ((NavigationPropertyLinkSegment)odataPath.LastSegment).NavigationProperty.Name;

            using (var messageReader = new ODataMessageReader(requestMessage, this.GetReaderSettings(), this.DataSource.Model))
            {
                var referenceLink = messageReader.ReadEntityReferenceLink();
                var queryContext = new QueryContext(this.ServiceRootUri, referenceLink.Url, this.DataSource.Model);
                var target = queryContext.ResolveQuery(this.DataSource);

                this.DataSource.UpdateProvider.UpdateLink(parent, navigationPropertyName, target);
                this.DataSource.UpdateProvider.SaveChanges();
            }

            ResponseWriter.WriteEmptyResponse(responseMessage);
        }
Exemple #4
0
 internal override IEnumerable<ODataPayloadKind> DetectPayloadKind(IODataRequestMessage requestMessage, ODataPayloadKindDetectionInfo detectionInfo)
 {
     ExceptionUtils.CheckArgumentNotNull<IODataRequestMessage>(requestMessage, "requestMessage");
     ExceptionUtils.CheckArgumentNotNull<ODataPayloadKindDetectionInfo>(detectionInfo, "detectionInfo");
     Stream messageStream = ((ODataMessage) requestMessage).GetStream();
     return this.DetectPayloadKindImplementation(messageStream, false, true, detectionInfo);
 }
        public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
        {
            string asyncToken = this.QueryContext.AsyncToken;
            AsyncTask asyncTask = AsyncTask.GetTask(asyncToken);

            if (asyncTask == null)
            {
                // token is invalid or expired. 
                throw Utility.BuildException(HttpStatusCode.NotFound);
            }
            else
            {
                if (!asyncTask.Ready)
                {
                    ResponseWriter.WriteAsyncPendingResponse(responseMessage, asyncToken);
                }
                else
                {
                    responseMessage.SetHeader(ServiceConstants.HttpHeaders.ContentType, "application/http");
                    responseMessage.SetHeader(ServiceConstants.HttpHeaders.ContentTransferEncoding, ServiceConstants.HttpHeaderValues.Binary);
                    using (var messageWriter = this.CreateMessageWriter(responseMessage))
                    {
                        var asyncWriter = messageWriter.CreateODataAsynchronousWriter();
                        var innerResponse = asyncWriter.CreateResponseMessage();
                        asyncTask.Execute(innerResponse);
                    }
                }
            }
        }
        public static void InitClass(TestContext testContext)
        {
            RequestWithApplicationJson = new ODataRequestMessageSimulator();
            RequestWithApplicationJson.SetHeader(XmlConstants.HttpContentType, "aPPlicaTion/jSoN");

            ResponseWithApplicationJson = new ODataResponseMessageSimulator();
            ResponseWithApplicationJson.SetHeader(XmlConstants.HttpContentType, "aPPlicaTion/jSoN");
        }
 public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
 {
     responseMessage.SetStatusCode(HttpStatusCode.OK);
     using (var writer = this.CreateMessageWriter(responseMessage))
     {
         writer.WriteServiceDocument(this.GenerateServiceDocument());
     }
 }
 /// <summary>
 /// Create a new feed generator
 /// </summary>
 /// <param name="requestMessage">The OData request message that was received</param>
 /// <param name="responseMessage">The OData response message to be populated by the generator</param>
 /// <param name="entityMap">The map to use to map RDF URIs to OData types and properties</param>
 /// <param name="baseUri">The base URI for the OData feed</param>
 /// <param name="messageWriterSettings">Additional settings to apply to the generated OData output</param>
 public ODataFeedGenerator(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage, SparqlMap entityMap, string baseUri, ODataMessageWriterSettings messageWriterSettings)
 {
     _request = requestMessage;
     _response = responseMessage;
     _map = entityMap;
     _baseUri = baseUri;
     _writerSettings = messageWriterSettings;
 }
        /// <summary>
        /// Constructs an internal wrapper around the <paramref name="requestMessage"/>
        /// that isolates the internal implementation of the ODataLib from the interface.
        /// </summary>
        /// <param name="requestMessage">The request message to wrap.</param>
        /// <param name="writing">true if the request message is being written; false when it is read.</param>
        /// <param name="disableMessageStreamDisposal">true if the stream returned should ignore dispose calls.</param>
        /// <param name="maxMessageSize">The maximum size of the message in bytes (or a negative value if no maximum applies).</param>
        internal ODataRequestMessage(IODataRequestMessage requestMessage, bool writing, bool disableMessageStreamDisposal, long maxMessageSize)
            : base(writing, disableMessageStreamDisposal, maxMessageSize)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(requestMessage != null, "requestMessage != null");

            this.requestMessage = requestMessage;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ClientPreference"/> class.
 /// </summary>
 /// <param name="requestDescription">The request description.</param>
 /// <param name="verb">The request verb.</param>
 /// <param name="requestMessage">The request message.</param>
 /// <param name="effectiveMaxResponseVersion">The effective max response version for the request, which is the min of MDSV and MPV.</param>
 public ClientPreference(RequestDescription requestDescription, HttpVerbs verb, IODataRequestMessage requestMessage, Version effectiveMaxResponseVersion)
     : this(InterpretClientPreference(requestDescription, verb, requestMessage))
 {
     if (effectiveMaxResponseVersion >= VersionUtil.Version4Dot0)
     {
         this.annotationFilter = requestMessage.PreferHeader().AnnotationFilter;
     }
 }
Exemple #11
0
        public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
        {
            if (this.TryDispatch(requestMessage, responseMessage))
            {
                return;
            }

            if (this.QueryContext.Target.TypeKind != EdmTypeKind.Collection)
            {
                throw Utility.BuildException(HttpStatusCode.BadRequest, "The new resource can only be created under collection resource.", null);
            }

            if (this.QueryContext.Target.IsReference)
            {
                this.ProcessCreateLink(requestMessage, responseMessage);
                return;
            }

            try
            {
                var targetEntitySet = (IEdmEntitySetBase)this.QueryContext.Target.NavigationSource;

                // TODO: [lianw] Try to remove "targetEntitySet" later.
                var queryResults = this.QueryContext.ResolveQuery(this.DataSource);

                if (!IsAllowInsert(targetEntitySet as IEdmEntitySet))
                {
                    throw new ODataServiceException(HttpStatusCode.BadRequest, "The insert request is not allowed.", null);
                }

                var bodyObject = ProcessPostBody(requestMessage, targetEntitySet, queryResults);

                using (var messageWriter = this.CreateMessageWriter(responseMessage))
                {
                    this.DataSource.UpdateProvider.SaveChanges();

                    // 11.4.2 Create an Entity
                    // Upon successful completion the service MUST respond with either 201 Created, or 204 No Content if the request included a return Prefer header with a value of return=minimal.
                    responseMessage.SetStatusCode(HttpStatusCode.Created);
                    responseMessage.SetHeader(ServiceConstants.HttpHeaders.Location, Utility.BuildLocationUri(this.QueryContext, bodyObject).OriginalString);
                    var currentETag = Utility.GetETagValue(bodyObject);
                    // if the current entity has ETag field
                    if (currentETag != null)
                    {
                        responseMessage.SetHeader(ServiceConstants.HttpHeaders.ETag, currentETag);
                    }

                    ResponseWriter.WriteEntry(messageWriter.CreateODataEntryWriter(targetEntitySet), bodyObject, targetEntitySet, ODataVersion.V4, null);
                }
            }
            catch
            {
                this.DataSource.UpdateProvider.ClearChanges();
                throw;
            }
        }
        /// <summary>
        /// Detects the payload kinds supported by this format for the specified message payload.
        /// </summary>
        /// <param name="requestMessage">The request message with the payload stream.</param>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>The set of <see cref="ODataPayloadKind"/>s that are supported with the specified payload.</returns>
        internal override IEnumerable<ODataPayloadKind> DetectPayloadKind(
            IODataRequestMessage requestMessage,
            ODataPayloadKindDetectionInfo detectionInfo)
        {
            DebugUtils.CheckNoExternalCallers();
            ExceptionUtils.CheckArgumentNotNull(requestMessage, "requestMessage");
            ExceptionUtils.CheckArgumentNotNull(detectionInfo, "detectionInfo");

            return DetectPayloadKindImplementation(detectionInfo.ContentType);
        }
        /// <summary>
        /// Detects the payload kinds supported by this format for the specified message payload.
        /// </summary>
        /// <param name="requestMessage">The request message with the payload stream.</param>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>The set of <see cref="ODataPayloadKind"/>s that are supported with the specified payload.</returns>
        internal override IEnumerable<ODataPayloadKind> DetectPayloadKind(
            IODataRequestMessage requestMessage,
            ODataPayloadKindDetectionInfo detectionInfo)
        {
            DebugUtils.CheckNoExternalCallers();
            ExceptionUtils.CheckArgumentNotNull(requestMessage, "requestMessage");
            ExceptionUtils.CheckArgumentNotNull(detectionInfo, "detectionInfo");

            Stream messageStream = ((ODataMessage)requestMessage).GetStream();
            return this.DetectPayloadKindImplementation(messageStream, /*readingResponse*/ false, /*synchronous*/ true, detectionInfo);
        }
        /// <summary>
        /// Detects the payload kinds supported by this format for the specified message payload.
        /// </summary>
        /// <param name="requestMessage">The request message with the payload stream.</param>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>The set of <see cref="ODataPayloadKind"/>s that are supported with the specified payload.</returns>
        internal override IEnumerable<ODataPayloadKind> DetectPayloadKind(
            IODataRequestMessage requestMessage,
            ODataPayloadKindDetectionInfo detectionInfo)
        {
            DebugUtils.CheckNoExternalCallers();
            ExceptionUtils.CheckArgumentNotNull(requestMessage, "requestMessage");
            ExceptionUtils.CheckArgumentNotNull(detectionInfo, "detectionInfo");

            // Metadata is not supported in requests!
            return Enumerable.Empty<ODataPayloadKind>();
        }
        public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
        {
            using (var messageWriter = this.CreateMessageWriter(responseMessage))
            {
                ODataError error;
                HttpStatusCode statusCode;

                this.BuildODataError(out error, out statusCode);
                responseMessage.SetStatusCode(statusCode);
                messageWriter.WriteError(error, true);
            }
        }
 public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
 {
     switch (this.HttpMethod)
     {
         case HttpMethod.POST:
             this.ProcessCreate(requestMessage.GetStream(), responseMessage);
             break;
         case HttpMethod.PUT:
             this.ProcessUpdate(requestMessage.GetStream(), responseMessage);
             break;
     }
 }
Exemple #17
0
        /// <summary>
        /// Applies headers in the dictionary to a request message.
        /// </summary>
        /// <param name="headers">The dictionary with the headers to apply.</param>
        /// <param name="requestMessage">The request message to apply the headers to.</param>
        /// <param name="ignoreAcceptHeader">If set to true the Accept header will be ignored.</param>
        internal static void ApplyHeadersToRequest(HeaderCollection headers, IODataRequestMessage requestMessage, bool ignoreAcceptHeader)
        {
            // NetCF bug with how the enumerators for dictionaries work.
            foreach (KeyValuePair <string, string> header in headers.AsEnumerable().ToList())
            {
                if (string.Equals(header.Key, XmlConstants.HttpRequestAccept, StringComparison.Ordinal) && ignoreAcceptHeader)
                {
                    continue;
                }

                requestMessage.SetHeader(header.Key, header.Value);
            }
        }
Exemple #18
0
        /// <summary>
        /// Gets the <see cref="ODataMessageReader"/> for the <see cref="HttpRequest"/> stream.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="requestContainer">The dependency injection container for the request.</param>
        /// <returns>A task object that produces an <see cref="ODataMessageReader"/> when completed.</returns>
        public static ODataMessageReader GetODataMessageReader(this HttpRequest request, IServiceProvider requestContainer)
        {
            if (request == null)
            {
                throw Error.ArgumentNull("request");
            }

            IODataRequestMessage       oDataRequestMessage = ODataMessageWrapperHelper.Create(request.Body, request.Headers, requestContainer);
            ODataMessageReaderSettings settings            = requestContainer.GetRequiredService <ODataMessageReaderSettings>();
            ODataMessageReader         oDataMessageReader  = new ODataMessageReader(oDataRequestMessage, settings);

            return(oDataMessageReader);
        }
Exemple #19
0
        public void TestCreateODataResourceReader_WithoutEntitySetOrType_DoesNotThrow()
        {
            // Arrange
            IODataRequestMessage       request  = CreateRequest();
            ODataMessageReaderSettings settings = CreateSettings();
            IEdmModel model = CreateModel();

            using (ODataMessageReader reader = new ODataMessageReader(request, settings, model))
            {
                // Act & Assert
                ExceptionAssert.DoesNotThrow(() => reader.CreateODataResourceReader());
            }
        }
        public void TestReadEntityReferenceLink_WithNavigationProperty_DoesNotThrow()
        {
            // Arrange
            IODataRequestMessage       request  = CreateRequest("{\"@odata.id\":\"aa:b\"}");
            ODataMessageReaderSettings settings = CreateSettings();
            IEdmModel model = CreateModel();

            using (ODataMessageReader reader = new ODataMessageReader(request, settings, model))
            {
                // Act & Assert
                Assert.DoesNotThrow(() => reader.ReadEntityReferenceLink());
            }
        }
Exemple #21
0
        public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
        {
            switch (this.HttpMethod)
            {
            case HttpMethod.POST:
                this.ProcessCreate(requestMessage.GetStream(), responseMessage);
                break;

            case HttpMethod.PUT:
                this.ProcessUpdate(requestMessage.GetStream(), responseMessage);
                break;
            }
        }
Exemple #22
0
        public void TestCreateODataCollectionReader_WithoutTypeReference_Throws()
        {
            // Arrange
            IODataRequestMessage       request  = CreateRequest();
            ODataMessageReaderSettings settings = CreateSettings();
            IEdmModel model = CreateModel();

            using (ODataMessageReader reader = new ODataMessageReader(request, settings, model))
            {
                // Act & Assert
                ExceptionAssert.Throws <ODataException>(() => reader.CreateODataCollectionReader());
            }
        }
Exemple #23
0
        public void TestReadProperty_InJsonLight_WithoutStructuralPropertyOrTypeReference_DoesNotThrows()
        {
            // Arrange
            IODataRequestMessage       request  = CreateJsonLightRequest("{\"value\":1}");
            ODataMessageReaderSettings settings = CreateSettings();
            IEdmModel model = CreateModel();

            using (ODataMessageReader reader = new ODataMessageReader(request, settings, model))
            {
                // Act & Assert
                Assert.DoesNotThrow(() => reader.ReadProperty());
            }
        }
 public ODataMessageReader(IODataRequestMessage requestMessage, ODataMessageReaderSettings settings, IEdmModel model)
 {
     this.readerPayloadKind = ODataPayloadKind.Unsupported;
     ExceptionUtils.CheckArgumentNotNull <IODataRequestMessage>(requestMessage, "requestMessage");
     this.settings = (settings == null) ? new ODataMessageReaderSettings() : new ODataMessageReaderSettings(settings);
     ReaderValidationUtils.ValidateMessageReaderSettings(this.settings, false);
     this.readingResponse = false;
     this.message         = new ODataRequestMessage(requestMessage, false, this.settings.DisableMessageStreamDisposal, this.settings.MessageQuotas.MaxReceivedMessageSize);
     this.urlResolver     = requestMessage as IODataUrlResolver;
     this.version         = ODataUtilsInternal.GetDataServiceVersion(this.message, this.settings.MaxProtocolVersion);
     this.model           = model ?? EdmCoreModel.Instance;
     ODataVersionChecker.CheckVersionSupported(this.version, this.settings);
 }
Exemple #25
0
        public void TestCreateODataEntryReader_InJsonLight_WithoutEntitySetOrType_Throws()
        {
            // Arrange
            IODataRequestMessage       request  = CreateJsonLightRequest();
            ODataMessageReaderSettings settings = CreateSettings();
            IEdmModel model = CreateModel();

            using (ODataMessageReader reader = new ODataMessageReader(request, settings, model))
            {
                // Act & Assert
                Assert.Throws <ODataException>(() => reader.CreateODataEntryReader());
            }
        }
Exemple #26
0
        public void TestReadEntityReferenceLink_InJsonLight_WithoutNavigationProperty_Throws()
        {
            // Arrange
            IODataRequestMessage       request  = CreateJsonLightRequest("{\"url\":\"aa:b\"}");
            ODataMessageReaderSettings settings = CreateSettings();
            IEdmModel model = CreateModel();

            using (ODataMessageReader reader = new ODataMessageReader(request, settings, model))
            {
                // Act & Assert
                Assert.Throws <ODataException>(() => reader.ReadEntityReferenceLink());
            }
        }
            /// <summary>
            /// Populates the given headers by accessing an expected property called 'Headers' on the given object,
            /// which must have an 'AllKeys' property and indexer, similar to WebHeaderCollection
            /// </summary>
            /// <param name="target">The object to get headers from</param>
            /// <param name="toPopulate">The headers to populate</param>
            private static void PopulateHeaders(object target, IDictionary <string, string> toPopulate)
            {
                ExceptionUtilities.CheckArgumentNotNull(target, "target");
                ExceptionUtilities.CheckArgumentNotNull(toPopulate, "toPopulate");

                IEnumerable <KeyValuePair <string, string> > headersDictionary = null;
                WebHeaderCollection   webHeadersCollection = null;
                IODataResponseMessage responseMessage      = target as IODataResponseMessage;

                if (responseMessage != null)
                {
                    headersDictionary = responseMessage.Headers;
                }

                IODataRequestMessage requestMessage = target as IODataRequestMessage;

                if (requestMessage != null)
                {
                    headersDictionary = requestMessage.Headers;
                }

                HttpWebRequest httpWebRequest = target as HttpWebRequest;

                if (httpWebRequest != null)
                {
                    webHeadersCollection = httpWebRequest.Headers;
                }

                HttpWebResponse httpWebResponse = target as HttpWebResponse;

                if (httpWebResponse != null)
                {
                    webHeadersCollection = httpWebResponse.Headers;
                }

                if (webHeadersCollection != null)
                {
                    foreach (var header in webHeadersCollection.AllKeys)
                    {
                        toPopulate[header] = webHeadersCollection[header];
                    }
                }
                else
                {
                    ExceptionUtilities.CheckObjectNotNull(headersDictionary, "Expected to find a Headers list");
                    foreach (var header in headersDictionary)
                    {
                        toPopulate[header.Key] = header.Value;
                    }
                }
            }
Exemple #28
0
        public async Task TestReadProperty_WithoutStructuralPropertyOrTypeReference_DoesNotThrows()
        {
            // Arrange
            IODataRequestMessage request = await CreateRequest("{\"value\":1}");

            ODataMessageReaderSettings settings = CreateSettings();
            IEdmModel model = CreateModel();

            using (ODataMessageReader reader = new ODataMessageReader(request, settings, model))
            {
                // Act & Assert
                ExceptionAssert.DoesNotThrow(() => reader.ReadProperty());
            }
        }
Exemple #29
0
        public async Task TestReadEntityReferenceLink_WithoutNavigationProperty_Throws()
        {
            // Arrange
            IODataRequestMessage request = await CreateRequest("{\"odata.id\":\"aa:b\"}");

            ODataMessageReaderSettings settings = CreateSettings();
            IEdmModel model = CreateModel();

            using (ODataMessageReader reader = new ODataMessageReader(request, settings, model))
            {
                // Act & Assert
                ExceptionAssert.Throws <ODataException>(() => reader.ReadEntityReferenceLink());
            }
        }
        public void TestCreateODataEntryReader_InJsonLight_WithEntityTypeButWithoutSet_Throws()
        {
            // Arrange
            IODataRequestMessage       request  = CreateJsonLightRequest();
            ODataMessageReaderSettings settings = CreateSettings();
            IEdmModel      model      = CreateModel();
            IEdmEntityType entityType = model.EntityContainer.EntitySets().First().EntityType();

            using (ODataMessageReader reader = new ODataMessageReader(request, settings, model))
            {
                // Act & Assert
                Assert.Throws <ODataException>(() => reader.CreateODataEntryReader(null, entityType));
            }
        }
Exemple #31
0
        public static ODataMessageReader GetODataMessageReader(this HttpRequest request, IServiceProvider requestContainer)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            // how to dispose it?
            IODataRequestMessage       oDataRequestMessage = ODataMessageWrapperHelper.Create(request.Body, request.Headers, requestContainer);
            ODataMessageReaderSettings settings            = requestContainer.GetRequiredService <ODataMessageReaderSettings>();
            ODataMessageReader         oDataMessageReader  = new ODataMessageReader(oDataRequestMessage, settings);

            return(oDataMessageReader);
        }
Exemple #32
0
        public void TestCreateODataResourceReader_WithComplexTypeButWithoutSet_DoesnotThrow()
        {
            // Arrange
            IODataRequestMessage       request  = CreateRequest();
            ODataMessageReaderSettings settings = CreateSettings();
            IEdmModel       model       = CreateModel();
            IEdmComplexType complexType = model.SchemaElements.OfType <IEdmComplexType>().First();

            using (ODataMessageReader reader = new ODataMessageReader(request, settings, model))
            {
                // Act & Assert
                ExceptionAssert.DoesNotThrow(() => reader.CreateODataResourceReader(null, complexType));
            }
        }
        public void TestReadProperty_InJsonLight_WithStructuralProperty_DoesNotThrow()
        {
            // Arrange
            IODataRequestMessage       request  = CreateJsonLightRequest("{\"value\":1}");
            ODataMessageReaderSettings settings = CreateSettings();
            IEdmModel model = CreateModel();
            IEdmStructuralProperty property = model.EntityContainer.EntitySets().First().EntityType().StructuralProperties().First();

            using (ODataMessageReader reader = new ODataMessageReader(request, settings, model))
            {
                // Act & Assert
                Assert.DoesNotThrow(() => reader.ReadProperty(property));
            }
        }
        /// <summary>
        /// Read and deserialize incoming object from HTTP request stream.
        /// </summary>
        /// <param name="type">incoming request body object type.</param>
        /// <param name="defaultValue">default value for this type.</param>
        /// <param name="model">Edm model to reference when validating.</param>
        /// <param name="baseAddress">Base address of request.</param>
        /// <param name="internalRequest">HTTP request method that contains ODataPath.</param>
        /// <param name="getODataRequestMessage">Function to obtain customized ODataMessageWrapper.</param>
        /// <param name="getEdmTypeDeserializer">Function to obtain appropriate edm deserializer.</param>
        /// <param name="getODataPayloadDeserializer">Function to obtain appropriate deserialize for function payloads.</param>
        /// <param name="getODataDeserializerContext">Context for Deserializer.</param>
        /// <param name="registerForDisposeAction">Registration function for disposables.</param>
        /// <returns>Deserialized object.</returns>
        internal object ReadFromStream(
            Type type,
            object defaultValue,
            IEdmModel model,
            Uri baseAddress,
            HttpRequest internalRequest,
            Func <IODataRequestMessage> getODataRequestMessage,
            Func <IEdmTypeReference, ODataDeserializer> getEdmTypeDeserializer,
            Func <Type, ODataDeserializer> getODataPayloadDeserializer,
            Func <ODataDeserializerContext> getODataDeserializerContext,
            Action <IDisposable> registerForDisposeAction,
            Action <Exception> logErrorAction)
        {
            object result;

            IEdmTypeReference expectedPayloadType;
            ODataPath         path         = internalRequest.ODataFeature().Path;
            ODataDeserializer deserializer = GetDeserializer(type, path, model, getEdmTypeDeserializer, getODataPayloadDeserializer, out expectedPayloadType);

            if (deserializer == null)
            {
                throw new ArgumentException("type", "Formatter does not support reading type " + type.FullName);
            }

            try
            {
                ODataMessageReaderSettings oDataReaderSettings = internalRequest.GetReaderSettings();
                oDataReaderSettings.BaseUri     = baseAddress;
                oDataReaderSettings.Validations = oDataReaderSettings.Validations & ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType;

                IODataRequestMessage oDataRequestMessage = getODataRequestMessage();
                ODataMessageReader   oDataMessageReader  = new ODataMessageReader(oDataRequestMessage, oDataReaderSettings, model);
                registerForDisposeAction(oDataMessageReader);

                ODataDeserializerContext readContext = getODataDeserializerContext();
                readContext.Path            = path;
                readContext.Model           = model;
                readContext.ResourceType    = type;
                readContext.ResourceEdmType = expectedPayloadType;

                result = deserializer.Read(oDataMessageReader, type, readContext);
            }
            catch (Exception e)
            {
                logErrorAction(e);
                result = defaultValue;
            }

            return(result);
        }
        /// <summary>
        /// Creates a writer for the given request message and settings.
        /// </summary>
        /// <param name="requestMessage">The request message.</param>
        /// <param name="writerSettings">The writer settings.</param>
        /// <param name="isParameterPayload">true if the writer is intended to for a parameter payload, false otherwise.</param>
        /// <returns>Newly created writer.</returns>
        internal ODataMessageWriter CreateWriter(IODataRequestMessage requestMessage, ODataMessageWriterSettings writerSettings, bool isParameterPayload)
        {
            Debug.Assert(requestMessage != null, "requestMessage != null");
            Debug.Assert(writerSettings != null, "writerSettings != null");

            this.requestInfo.Context.Format.ValidateCanWriteRequestFormat(requestMessage, isParameterPayload);

            // When calling Execute() to invoke an Action, the client doesn't support parsing the target url
            // to determine which IEdmOperationImport to pass to the ODL writer. So the ODL writer is
            // serializing the parameter payload without metadata. Setting the model to null so ODL doesn't
            // do unecessary validations when writing without metadata.
            var model = isParameterPayload ? null : this.requestInfo.Model;
            return new ODataMessageWriter(requestMessage, writerSettings, model);
        }
Exemple #36
0
        public async Task ExecuteOperationAsync_CopiesPropertiesFromRequest_WithoutExcludedProperties()
        {
            // Arrange
            RequestDelegate handler = context =>
            {
                context.Features[typeof(UnbufferedODataBatchHandlerTest)] = "foo";
                return(Task.FromResult(context.Response));
            };

            UnbufferedODataBatchHandler batchHandler = new UnbufferedODataBatchHandler();
            string batchRequest = @"--75148e61-e67a-4bb7-ac0f-78fa30d0da30
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 318941389

GET / HTTP/1.1
Host: example.com


--75148e61-e67a-4bb7-ac0f-78fa30d0da30--
";

            HttpRequest request     = RequestFactory.Create("Post", "http://example.com/$batch", opt => opt.AddModel(EdmCoreModel.Instance));
            HttpContext httpContext = request.HttpContext;

            byte[] requestBytes = Encoding.UTF8.GetBytes(batchRequest);
            request.Body          = new MemoryStream(requestBytes);
            request.ContentType   = "multipart/mixed;boundary=\"75148e61-e67a-4bb7-ac0f-78fa30d0da30\"";
            request.ContentLength = 431;
            httpContext.ODataFeature().PrefixName = "";
            IServiceProvider sp = request.GetSubServiceProvider();

            IODataRequestMessage oDataRequestMessage = ODataMessageWrapperHelper.Create(httpContext.Request.Body, request.Headers, sp);
            ODataMessageReader   oDataMessageReader  = new ODataMessageReader(oDataRequestMessage, new ODataMessageReaderSettings {
                BaseUri = new Uri("http://example.com")
            });

            ODataBatchReader batchReader = await oDataMessageReader.CreateODataBatchReaderAsync();

            List <ODataBatchResponseItem> responses = new List <ODataBatchResponseItem>();
            await batchReader.ReadAsync();

            // Act
            var response = await batchHandler.ExecuteOperationAsync(batchReader, Guid.NewGuid(), httpContext.Request, handler);

            // Assert
            OperationResponseItem operationResponseItem = Assert.IsType <OperationResponseItem>(response);

            Assert.Equal("foo", operationResponseItem.Context.Features[typeof(UnbufferedODataBatchHandlerTest)]);
        }
        public void TestCreateODataEntryReader_InJsonLight_WithEntitySetButWithoutType_DoesNotThrow()
        {
            // Arrange
            IODataRequestMessage       request  = CreateJsonLightRequest();
            ODataMessageReaderSettings settings = CreateSettings();
            IEdmModel     model     = CreateModel();
            IEdmEntitySet entitySet = model.EntityContainer.EntitySets().First();

            using (ODataMessageReader reader = new ODataMessageReader(request, settings, model))
            {
                // Act & Assert
                Assert.DoesNotThrow(() => reader.CreateODataEntryReader(entitySet, null));
            }
        }
Exemple #38
0
        public void TestReadEntityReferenceLink_InJsonLight_WithNavigationProperty_DoesNotThrow()
        {
            // Arrange
            IODataRequestMessage       request  = CreateJsonLightRequest("{\"url\":\"aa:b\"}");
            ODataMessageReaderSettings settings = CreateSettings();
            IEdmModel model = CreateModel();
            IEdmNavigationProperty navigationProperty =
                model.EntityContainers().Single().EntitySets().First().NavigationTargets.First().NavigationProperty;

            using (ODataMessageReader reader = new ODataMessageReader(request, settings, model))
            {
                // Act & Assert
                Assert.DoesNotThrow(() => reader.ReadEntityReferenceLink(navigationProperty));
            }
        }
        /// <summary>
        /// Creates a writer for the given request message and settings.
        /// </summary>
        /// <param name="requestMessage">The request message.</param>
        /// <param name="writerSettings">The writer settings.</param>
        /// <param name="isParameterPayload">true if the writer is intended to for a parameter payload, false otherwise.</param>
        /// <returns>Newly created writer.</returns>
        internal ODataMessageWriter CreateWriter(IODataRequestMessage requestMessage, ODataMessageWriterSettings writerSettings, bool isParameterPayload)
        {
            Debug.Assert(requestMessage != null, "requestMessage != null");
            Debug.Assert(writerSettings != null, "writerSettings != null");

            DataServiceClientFormat.ValidateCanWriteRequestFormat(requestMessage);

            // When calling Execute() to invoke an Action, the client doesn't support parsing the target url
            // to determine which IEdmOperationImport to pass to the ODL writer. So the ODL writer is
            // serializing the parameter payload without metadata. Setting the model to null so ODL doesn't
            // do unnecessary validations when writing without metadata.
            var model = isParameterPayload ? null : this.requestInfo.Model;

            return(new ODataMessageWriter(requestMessage, writerSettings, model));
        }
Exemple #40
0
        public void TestCreateODataCollectionReader_WithTypeReference_DoesNotThrow()
        {
            // Arrange
            IODataRequestMessage       request          = CreateRequest();
            ODataMessageReaderSettings settings         = CreateSettings();
            IEdmModel         model                     = CreateModel();
            IEdmTypeReference expectedItemTypeReference = new EdmPrimitiveTypeReference(
                EdmCoreModel.Instance.GetPrimitiveType(EdmPrimitiveTypeKind.Int32), false);

            using (ODataMessageReader reader = new ODataMessageReader(request, settings, model))
            {
                // Act & Assert
                ExceptionAssert.DoesNotThrow(() => reader.CreateODataCollectionReader(expectedItemTypeReference));
            }
        }
        public void TestReadProperty_InJsonLight_WithTypeReference_DoesNotThrow()
        {
            // Arrange
            IODataRequestMessage       request              = CreateJsonLightRequest("{\"value\":1}");
            ODataMessageReaderSettings settings             = CreateSettings();
            IEdmModel         model                         = CreateModel();
            IEdmTypeReference expectedPropertyTypeReference = new EdmPrimitiveTypeReference(
                EdmCoreModel.Instance.GetPrimitiveType(EdmPrimitiveTypeKind.Int32), false);

            using (ODataMessageReader reader = new ODataMessageReader(request, settings, model))
            {
                // Act & Assert
                Assert.DoesNotThrow(() => reader.ReadProperty(expectedPropertyTypeReference));
            }
        }
        public static void SetODataRequestContent(IODataRequestMessage requestMessage, IEdmModel model, IInventoryItem inventoryItem)
        {
            var setting = new ODataMessageWriterSettings();

            setting.SetContentType(ODataFormat.Atom);
            ODataMessageWriter oDatamessageWriter = new ODataMessageWriter(requestMessage, setting, model);
            ODataWriter        oDataEntrywriter   = oDatamessageWriter.CreateODataEntryWriter();

            oDataEntrywriter.WriteStart(new ODataEntry()
            {
                TypeName   = TypeName,
                Properties = GetODataProperties(inventoryItem)
            });

            oDataEntrywriter.WriteEnd();
        }
        public void TestCreateODataCollectionReader_InJsonLight_WithTypeReference_DoesNotThrow()
        {
            // Arrange
            IODataRequestMessage       request            = CreateJsonLightRequest();
            ODataMessageReaderSettings settings           = CreateSettings();
            IEdmModel           model                     = CreateModel();
            IEdmOperationImport producingOperationImport  = model.EntityContainer.OperationImports().First();
            IEdmTypeReference   expectedItemTypeReference = new EdmPrimitiveTypeReference(
                EdmCoreModel.Instance.GetPrimitiveType(EdmPrimitiveTypeKind.Int32), false);

            using (ODataMessageReader reader = new ODataMessageReader(request, settings, model))
            {
                // Act & Assert
                Assert.DoesNotThrow(() => reader.CreateODataCollectionReader(expectedItemTypeReference));
            }
        }
Exemple #44
0
        /// <summary>
        /// Gets the <see cref="ODataMessageReader"/> for the <see cref="HttpContent"/> stream.
        /// </summary>
        /// <param name="content">The <see cref="HttpContent"/>.</param>
        /// <param name="settings">The <see cref="ODataMessageReaderSettings"/>.</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
        /// <returns>A task object that produces an <see cref="ODataMessageReader"/> when completed.</returns>
        public static async Task <ODataMessageReader> GetODataMessageReaderAsync(this HttpContent content,
                                                                                 ODataMessageReaderSettings settings, CancellationToken cancellationToken)
        {
            if (content == null)
            {
                throw Error.ArgumentNull("content");
            }

            cancellationToken.ThrowIfCancellationRequested();
            Stream contentStream = await content.ReadAsStreamAsync();

            IODataRequestMessage oDataRequestMessage = ODataMessageWrapperHelper.Create(contentStream, content.Headers, new MockContainer());
            ODataMessageReader   oDataMessageReader  = new ODataMessageReader(oDataRequestMessage, settings);

            return(oDataMessageReader);
        }
Exemple #45
0
        private Expression[] ProcessActionInvokePostBody(IODataRequestMessage message, IEdmOperation operation)
        {
            using (var messageReader = new ODataMessageReader(message, this.GetReaderSettings()))
            {
                List <Expression> parameterValues = new List <Expression>();
                var parameterReader = messageReader.CreateODataParameterReader(operation);

                while (parameterReader.Read())
                {
                    switch (parameterReader.State)
                    {
                    case ODataParameterReaderState.Value:
                    {
                        object clrValue = ODataObjectModelConverter.ConvertPropertyValue(parameterReader.Value);
                        parameterValues.Add(Expression.Constant(clrValue));
                        break;
                    }

                    case ODataParameterReaderState.Collection:
                    {
                        ODataCollectionReader collectionReader = parameterReader.CreateCollectionReader();
                        object clrValue = ODataObjectModelConverter.ConvertPropertyValue(ODataObjectModelConverter.ReadCollectionParameterValue(collectionReader));
                        parameterValues.Add(Expression.Constant(clrValue, clrValue.GetType()));
                        break;
                    }

                    case ODataParameterReaderState.Resource:
                    {
                        var    entryReader = parameterReader.CreateResourceReader();
                        object clrValue    = ODataObjectModelConverter.ReadEntityOrEntityCollection(entryReader, false);
                        parameterValues.Add(Expression.Constant(clrValue, clrValue.GetType()));
                        break;
                    }

                    case ODataParameterReaderState.ResourceSet:
                    {
                        var feedReader     = parameterReader.CreateResourceSetReader();
                        var collectionList = ODataObjectModelConverter.ReadEntityOrEntityCollection(feedReader, true);
                        parameterValues.Add(Expression.Constant(collectionList, collectionList.GetType()));
                        break;
                    }
                    }
                }

                return(parameterValues.ToArray());
            }
        }
        public void RequestMessageHeaderTest()
        {
            Func <bool, IODataRequestMessage>[] requestMessageFuncs = new Func <bool, IODataRequestMessage>[]
            {
                (writing) => CreateBatchOperationRequestMessage(writing),
                (writing) => new ODataRequestMessageWrapper(new TestRequestMessage(new TestStream()), writing, false),
            };

            this.CombinatorialEngineProvider.RunCombinations(
                new bool[] { true, false },
                requestMessageFuncs,
                (writing, func) =>
            {
                IODataRequestMessage requestMessage = func(writing);
                RunHeaderTest(() => requestMessage.Headers, writing, requestMessage.GetHeader, requestMessage.SetHeader, this.Assert, this.ExceptionVerifier);
            });
        }
        internal static async Task <object> ReadFromStreamAsync(Type type, object defaultValue, Uri baseAddress, HttpRequest request, IList <IDisposable> disposes)
        {
            object            result;
            IEdmModel         model = request.GetModel();
            IEdmTypeReference expectedPayloadType;
            ODataDeserializer deserializer = GetDeserializer(request, type, out expectedPayloadType);

            if (deserializer == null)
            {
                throw Error.Argument("type", SRResources.FormatterReadIsNotSupportedForType, type.FullName, typeof(ODataInputFormatter).FullName);
            }

            try
            {
                ODataMessageReaderSettings oDataReaderSettings = request.GetReaderSettings();
                oDataReaderSettings.BaseUri     = baseAddress;
                oDataReaderSettings.Validations = oDataReaderSettings.Validations & ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType;

                // WebAPI should read untyped values as structural values by setting ReadUntypedAsString=false.
                // In ODL 8.x, ReadUntypedAsString option will be deleted.
                oDataReaderSettings.ReadUntypedAsString = false;

                IODataRequestMessage oDataRequestMessage =
                    ODataMessageWrapperHelper.Create(new StreamWrapper(request.Body), request.Headers, request.GetODataContentIdMapping(), request.GetSubServiceProvider());
                ODataMessageReader oDataMessageReader = new ODataMessageReader(oDataRequestMessage, oDataReaderSettings, model);
                disposes.Add(oDataMessageReader);

                ODataPath path = request.ODataFeature().Path;
                ODataDeserializerContext readContext = BuildDeserializerContext(request);

                readContext.Path            = path;
                readContext.Model           = model;
                readContext.ResourceType    = type;
                readContext.ResourceEdmType = expectedPayloadType;

                result = await deserializer.ReadAsync(oDataMessageReader, type, readContext).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                LoggerError(request.HttpContext, ex);
                result = defaultValue;
            }

            return(result);
        }
Exemple #48
0
        internal BatchServiceHost(Uri absoluteServiceUri, IODataRequestMessage operationMessage, string contentId, ODataBatchWriter writer, Version maxDataServiceVersion, Version minDataServiceVersion, Version dataServiceVersion) : this(writer)
        {
            this.absoluteServiceUri = absoluteServiceUri;
			this.absoluteRequestUri = RequestUriProcessor.GetAbsoluteUriFromReference(operationMessage.Url, absoluteServiceUri, dataServiceVersion);
            this.requestHttpMethod = operationMessage.Method;
            this.contentId = contentId;
            foreach (KeyValuePair<string, string> pair in operationMessage.Headers)
            {
                this.requestHeaders.Add(pair.Key, pair.Value);
            }
            if (string.IsNullOrEmpty(this.requestHeaders["MaxDataServiceVersion"]))
            {
                this.requestHeaders["MaxDataServiceVersion"] = maxDataServiceVersion.ToString();
            }
            if (string.IsNullOrEmpty(this.requestHeaders["MinDataServiceVersion"]))
            {
                this.requestHeaders["MinDataServiceVersion"] = minDataServiceVersion.ToString();
            }
            this.requestStream = operationMessage.GetStream();
        }
Exemple #49
0
        public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
        {
            try
            {
                var odataPath = this.QueryContext.QueryPath;

                if (this.QueryContext.Target.IsReference && this.QueryContext.Target.TypeKind != EdmTypeKind.Collection)
                {
                    ProcessUpdateEntityReference(requestMessage, responseMessage, odataPath);
                }
                else
                {
                    ProcessUpdateOrUpsertEntity(requestMessage, responseMessage, odataPath);
                }
            }
            catch
            {
                this.DataSource.UpdateProvider.ClearChanges();
                throw;
            }
        }
        public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
        {
            // TODO: we will need to add server-driven paging for delta link

            object queryResults = this.QueryContext.ResolveQuery(this.DataSource);

            using (var messageWriter = this.CreateMessageWriter(responseMessage))
            {
                IEdmNavigationSource navigationSource = this.QueryContext.Target.NavigationSource;
                IEnumerable iEnumerableResults = queryResults as IEnumerable;

                if (this.QueryContext.Target.NavigationSource != null && this.QueryContext.Target.TypeKind == EdmTypeKind.Collection)
                {
                    IEdmEntitySetBase entitySet = navigationSource as IEdmEntitySetBase;
                    IEdmEntityType entityType = this.QueryContext.Target.ElementType as IEdmEntityType;
                    if (entitySet == null || entityType == null)
                    {
                        throw new InvalidOperationException("Invalid target when query feed.");
                    }
                    GenerateDeltaItemsFromFeed(iEnumerableResults, entitySet, ODataVersion.V4, this.QueryContext.QuerySelectExpandClause);

                    Uri newDeltaLink = null;
                    if (this.PreferenceContext.TrackingChanges)
                    {
                        var newDeltaToken = DeltaContext.GenerateDeltaToken(this.QueryContext.QueryUri, iEnumerableResults, entitySet, this.QueryContext.QuerySelectExpandClause);
                        newDeltaLink = new Uri(string.Format("{0}?{1}={2}", this.ServiceRootUri, ServiceConstants.QueryOption_Delta, newDeltaToken));
                        responseMessage.AddPreferenceApplied(ServiceConstants.Preference_TrackChanging);
                    }
                    ODataDeltaWriter resultWriter = messageWriter.CreateODataDeltaWriter(entitySet, entityType);
                    ResponseWriter.WriteDeltaFeed(resultWriter, this.DeltaItems, this.QueryContext.CountOption, newDeltaLink);

                    resultWriter.Flush();
                }
                else
                {
                    throw Utility.BuildException(HttpStatusCode.Gone);
                }
            }
        }
        public ODataResponseContext(IODataRequestMessage requestMessage, ODataFormat format, ODataVersion version, Uri baseAddress, string serviceOperationName)
        {
            if (requestMessage == null)
            {
                throw Error.ArgumentNull("requestMessage");
            }

            if (baseAddress == null)
            {
                throw Error.ArgumentNull("baseAddress");
            }

            if (String.IsNullOrEmpty(serviceOperationName))
            {
                throw Error.ArgumentNullOrEmpty("serviceOperationName");
            }

            _requestMessage = requestMessage;
            ODataFormat = format;
            ODataVersion = version;
            _baseAddress = baseAddress;
            _serviceOperationName = serviceOperationName;
            IsIndented = true;
        }
        private Expression[] ProcessActionInvokePostBody(IODataRequestMessage message, IEdmOperation operation)
        {
            using (var messageReader = new ODataMessageReader(message, this.GetReaderSettings(), this.DataSource.Model))
            {
                List<Expression> parameterValues = new List<Expression>();
                var parameterReader = messageReader.CreateODataParameterReader(operation);

                while (parameterReader.Read())
                {
                    switch (parameterReader.State)
                    {
                        case ODataParameterReaderState.Value:
                            {
                                object clrValue = ODataObjectModelConverter.ConvertPropertyValue(parameterReader.Value);
                                parameterValues.Add(Expression.Constant(clrValue));
                                break;
                            }
                        case ODataParameterReaderState.Collection:
                            {
                                ODataCollectionReader collectionReader = parameterReader.CreateCollectionReader();
                                object clrValue = ODataObjectModelConverter.ConvertPropertyValue(ODataObjectModelConverter.ReadCollectionParameterValue(collectionReader));
                                parameterValues.Add(Expression.Constant(clrValue, clrValue.GetType()));
                                break;
                            }
                        case ODataParameterReaderState.Entry:
                            {
                                var entryReader = parameterReader.CreateEntryReader();
                                object clrValue = ODataObjectModelConverter.ConvertPropertyValue(ODataObjectModelConverter.ReadEntryParameterValue(entryReader));
                                parameterValues.Add(Expression.Constant(clrValue, clrValue.GetType()));
                                break;
                            }
                        case ODataParameterReaderState.Feed:
                            {
                                IList collectionList = null;
                                var feedReader = parameterReader.CreateFeedReader();
                                while (feedReader.Read())
                                {
                                    if (feedReader.State == ODataReaderState.EntryEnd)
                                    {
                                        object clrItem = ODataObjectModelConverter.ConvertPropertyValue(feedReader.Item);
                                        if (collectionList == null)
                                        {
                                            Type itemType = clrItem.GetType();
                                            Type listType = typeof(List<>).MakeGenericType(new[] { itemType });
                                            collectionList = (IList)Utility.QuickCreateInstance(listType);
                                        }

                                        collectionList.Add(clrItem);
                                    }
                                }

                                parameterValues.Add(Expression.Constant(collectionList, collectionList.GetType()));
                                break;
                            }
                    }
                }

                return parameterValues.ToArray();
            }
        }
 private static ODataMessageReader GetODataMessageReader(IODataRequestMessage oDataRequestMessage, IEdmModel edmModel)
 {
     return new ODataMessageReader(oDataRequestMessage, new ODataMessageReaderSettings(), edmModel);
 }
        protected bool TryDispatch(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
        {
            RequestHandler handler = this.DispatchHandler();

            if (handler != null)
            {
                handler.Process(requestMessage, responseMessage);
                return true;
            }

            return false;
        }
        public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
        {
            object result;

            if (this.HttpMethod == HttpMethod.GET)
            {
                // we cannot invoke same action request multiple times, so only Functions are allowed to do the server-driven paging
                this.QueryContext.InitializeServerDrivenPaging(this.PreferenceContext);

                result = this.ProcessFunction();

                if (this.PreferenceContext.MaxPageSize.HasValue)
                {
                    responseMessage.AddPreferenceApplied(string.Format("{0}={1}", ServiceConstants.Preference_MaxPageSize, this.QueryContext.appliedPageSize.Value));
                }
            }
            else
            {
                // TODO: currently ETag feature does not support action operation

                result = this.ProcessAction(requestMessage);
            }

            if (result == null)
            {
                // Protocol 9.1.4 Response Code 204 No Content
                // A request returns 204 No Content if the requested resource has the null value, 
                // or if the service applies a return=minimal preference. In this case, the response body MUST be empty.
                ResponseWriter.WriteEmptyResponse(responseMessage);

                return;
            }

            using (var messageWriter = this.CreateMessageWriter(responseMessage))
            {
                if (this.QueryContext.Target.TypeKind == EdmTypeKind.None ||
                    this.QueryContext.Target.TypeKind == EdmTypeKind.EntityReference ||
                    this.QueryContext.Target.ElementTypeKind == EdmTypeKind.EntityReference)
                {
                    throw Utility.BuildException(HttpStatusCode.NotImplemented, "Unsupported return type in operation.", null);
                }
                else if (this.QueryContext.Target.TypeKind == EdmTypeKind.Entity || this.QueryContext.Target.ElementTypeKind == EdmTypeKind.Entity)
                {
                    ODataWriter resultWriter;

                    IEdmNavigationSource entitySource = this.QueryContext.OperationResultSource ?? this.QueryContext.Target.NavigationSource;

                    if (this.QueryContext.Target.TypeKind == EdmTypeKind.Collection)
                    {
                        IEdmEntitySetBase entitySet = (IEdmEntitySetBase)entitySource;

                        resultWriter = messageWriter.CreateODataFeedWriter(entitySet, (IEdmEntityType)this.QueryContext.Target.ElementType);
                        ResponseWriter.WriteFeed(resultWriter, (IEdmEntityType)this.QueryContext.Target.ElementType, result as IEnumerable, entitySet, ODataVersion.V4, this.QueryContext.QuerySelectExpandClause, this.QueryContext.TotalCount, null, this.QueryContext.NextLink, this.RequestHeaders);
                    }
                    else
                    {
                        if (this.HttpMethod == HttpMethod.GET)
                        {
                            var currentETag = Utility.GetETagValue(result);
                            // if the current entity has ETag field
                            if (currentETag != null)
                            {
                                string requestETag;
                                if (Utility.TryGetIfNoneMatch(this.RequestHeaders, out requestETag) && (requestETag == ServiceConstants.ETagValueAsterisk || requestETag == currentETag))
                                {
                                    ResponseWriter.WriteEmptyResponse(responseMessage, HttpStatusCode.NotModified);
                                    return;
                                }

                                responseMessage.SetHeader(ServiceConstants.HttpHeaders.ETag, currentETag);
                            }
                        }

                        resultWriter = messageWriter.CreateODataEntryWriter(entitySource, (IEdmEntityType)this.QueryContext.Target.Type);
                        ResponseWriter.WriteEntry(resultWriter, result, entitySource, ODataVersion.V4, this.QueryContext.QuerySelectExpandClause, this.RequestHeaders);
                    }
                }
                else
                {
                    ODataProperty property = new ODataProperty() { Name = "value", Value = ODataObjectModelConverter.CreateODataValue(result) };
                    messageWriter.WriteProperty(property);
                }
            }
        }
 public virtual void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
 {
     throw new NotImplementedException();
 }
 protected virtual ODataMessageReader CreateMessageReader(IODataRequestMessage message)
 {
     return new ODataMessageReader(
         message,
         this.GetReaderSettings(),
         this.DataSource.Model);
 }
Exemple #58
0
        private void ProcessUpsertEntity(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage, ODataPath odataPath)
        {
            if (this.QueryContext.Target.TypeKind == EdmTypeKind.Entity && !this.QueryContext.Target.IsReference)
            {
                Uri parentUri = this.QueryContext.Target.BuildContainerUri(this.ServiceRootUri);
                QueryContext parentContext = new QueryContext(this.ServiceRootUri, parentUri, this.DataSource.Model);

                if (parentContext.Target.IsEntitySet)
                {
                    // Update a entity under a entity set => Upsert

                    // TODO: Do we need to preserver the key value?
                    new CreateHandler(this, parentContext.QueryUri).Process(requestMessage, responseMessage);
                }
                else
                {
                    // Update Singleton or single value entity from null value.
                    var parent = parentContext.ResolveQuery(this.DataSource);

                    // TODO: It might not correct here, since the last segment could be type segment.
                    NavigationPropertySegment navSegment = (NavigationPropertySegment)odataPath.LastSegment;
                    var targetObject = Utility.CreateResource(this.QueryContext.Target.Type);
                    parent.GetType().GetProperty(navSegment.NavigationProperty.Name).SetValue(parent, targetObject, null);

                    ProcessUpdateRequestBody(requestMessage, responseMessage, targetObject, true);
                }
            }
            else
            {
                throw Utility.BuildException(HttpStatusCode.NotFound);
            }
        }
Exemple #59
0
        private void ProcessUpdateOrUpsertEntity(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage, ODataPath odataPath)
        {
            var targetObject = this.QueryContext.ResolveQuery(this.DataSource);
            string targetETag = null;

            if (targetObject != null)
            {
                targetETag = Utility.GetETagValue(targetObject);
            }

            var requestETagKind = RequestETagKind.None;
            string requestETag;
            if (Utility.TryGetIfMatch(this.RequestHeaders, out requestETag))
            {
                requestETagKind = RequestETagKind.IfMatch;
            }
            else if (Utility.TryGetIfNoneMatch(this.RequestHeaders, out requestETag))
            {
                requestETagKind = RequestETagKind.IfNoneMatch;
            }

            switch (requestETagKind)
            {
                case RequestETagKind.None:
                    {
                        if (targetETag == null)
                        {
                            if (targetObject == null)
                            {
                                ProcessUpsertEntity(requestMessage, responseMessage, odataPath);
                            }
                            else
                            {
                                ProcessUpdateRequestBody(requestMessage, responseMessage, targetObject, false);
                            }
                        }
                        else
                        {
                            ResponseWriter.WriteEmptyResponse(responseMessage, (HttpStatusCode)428);
                        }

                        break;
                    }
                case RequestETagKind.IfMatch:
                    {
                        if (requestETag == ServiceConstants.ETagValueAsterisk || requestETag == targetETag)
                        {
                            if (targetObject == null)
                            {
                                throw Utility.BuildException(HttpStatusCode.NotFound);
                            }

                            ProcessUpdateRequestBody(requestMessage, responseMessage, targetObject, false);
                        }
                        else
                        {
                            ResponseWriter.WriteEmptyResponse(responseMessage, HttpStatusCode.PreconditionFailed);
                        }

                        break;
                    }
                case RequestETagKind.IfNoneMatch:
                    {
                        if (requestETag == ServiceConstants.ETagValueAsterisk)
                        {
                            ProcessUpsertEntity(requestMessage, responseMessage, odataPath);
                        }
                        else if (requestETag != targetETag)
                        {
                            if (targetObject == null)
                            {
                                throw Utility.BuildException(HttpStatusCode.NotFound);
                            }

                            ProcessUpdateRequestBody(requestMessage, responseMessage, targetObject, false);
                        }
                        else
                        {
                            ResponseWriter.WriteEmptyResponse(responseMessage, HttpStatusCode.PreconditionFailed);
                        }

                        break;
                    }
            }
        }
Exemple #60
0
        private void ProcessUpdateRequestBody(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage, object targetObject, bool isUpsert)
        {
            if (this.QueryContext.Target.NavigationSource != null && this.QueryContext.Target.TypeKind == EdmTypeKind.Entity)
            {
                using (var messageReader = new ODataMessageReader(requestMessage, this.GetReaderSettings(), this.DataSource.Model))
                {
                    var entryReader = messageReader.CreateODataEntryReader(this.QueryContext.Target.NavigationSource, (IEdmEntityType)this.QueryContext.Target.Type);

                    while (entryReader.Read())
                    {
                        switch (entryReader.State)
                        {
                            case ODataReaderState.EntryEnd:
                                var entry = (ODataEntry)entryReader.Item;
                                foreach (var property in entry.Properties)
                                {
                                    if (Utility.IsETagProperty(targetObject, property.Name)) continue;
                                    // the property might be an open property, so test null first
                                    var propertyInfo = targetObject.GetType().GetProperty(property.Name);
                                    if (propertyInfo != null)
                                    {
                                        if (!isUpsert && Utility.IsReadOnly(propertyInfo)) continue;
                                    }

                                    this.DataSource.UpdateProvider.Update(targetObject, property.Name, property.Value);
                                }

                                break;
                        }
                    }
                }
            }
            else if (this.QueryContext.Target.Property != null && this.QueryContext.Target.TypeKind == EdmTypeKind.Complex)
            {
                using (var messageReader = new ODataMessageReader(requestMessage, this.GetReaderSettings(), this.DataSource.Model))
                {
                    var property = messageReader.ReadProperty(this.QueryContext.Target.Property);
                    ODataComplexValue complexValue = property.Value as ODataComplexValue;

                    foreach (var p in complexValue.Properties)
                    {
                        if (Utility.IsETagProperty(targetObject, property.Name)) continue;
                        this.DataSource.UpdateProvider.Update(targetObject, p.Name, p.Value);
                    }
                }
            }
            else
            {
                throw Utility.BuildException(
                    HttpStatusCode.NotImplemented,
                    string.Format("PATCH/PUT for '{0}' type is not supported.", this.QueryContext.Target.TypeKind),
                    null);
            }

            var currentETag = Utility.GetETagValue(targetObject);
            // if the current entity has ETag field
            if (currentETag != null)
            {
                if (!isUpsert)
                {
                    this.DataSource.UpdateProvider.UpdateETagValue(targetObject);
                }

                this.DataSource.UpdateProvider.SaveChanges();

                currentETag = Utility.GetETagValue(targetObject);
                responseMessage.SetHeader(ServiceConstants.HttpHeaders.ETag, currentETag);
            }
            else
            {
                this.DataSource.UpdateProvider.SaveChanges();
            }

            ResponseWriter.WriteEmptyResponse(responseMessage);
        }