Exemplo n.º 1
0
        /// <summary>Initializes a new NonEntitySerializer instance.</summary>
        /// <param name="requestDescription">Description of request.</param>
        /// <param name="absoluteServiceUri">Base URI from which resources should be resolved.</param>
        /// <param name="service">Service with configuration and provider from which metadata should be gathered.</param>
        /// <param name="messageWriter">ODataMessageWriter instance which needs to be used to write the response.</param>
        internal NonEntitySerializer(RequestDescription requestDescription, Uri absoluteServiceUri, IDataService service, ODataMessageWriter messageWriter)
            : base(requestDescription, absoluteServiceUri, service, null)
        {
            Debug.Assert(messageWriter != null, "messageWriter != null");

            this.writer = messageWriter;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Initializes a new instance of <see cref="Deserializer"/>.
        /// </summary>
        /// <param name="update">true if we're reading an update operation; false if not.</param>
        /// <param name="dataService">Data service for which the deserializer will act.</param>
        /// <param name="tracker">Tracker to use for modifications.</param>
        /// <param name="requestDescription">The request description to use.</param>
        internal Deserializer(bool update, IDataService dataService, UpdateTracker tracker, RequestDescription requestDescription)
        {
            Debug.Assert(dataService != null, "dataService != null");

            this.service = dataService;
            this.tracker = tracker;
            this.update = update;
            this.description = requestDescription;
        }
Exemplo n.º 3
0
 /// <summary>Initializes a new <see cref="Deserializer"/> based on a different one.</summary>
 /// <param name="parent">Parent deserializer for the new instance.</param>
 internal Deserializer(Deserializer parent)
 {
     Debug.Assert(parent != null, "parent != null");
     this.recursionDepth = parent.recursionDepth;
     this.service = parent.service;
     this.tracker = parent.tracker;
     this.update = parent.update;
     this.description = parent.description;
 }
        /// <summary>Initializes a new <see cref="RequestExpressionParser"/>.</summary>
        /// <param name="service">Service with data and configuration.</param>
        /// <param name="requestDescription">RequestDescription instance containing information about the current request being parsed.</param>
        internal RequestExpressionParser(IDataService service, RequestDescription requestDescription)
        {
            Debug.Assert(service != null, "service != null");
            Debug.Assert(requestDescription != null, "requestDescription != null");

            this.provider = service.Provider;

            this.model = this.provider.GetMetadataProviderEdmModel();

            this.odataUriParser = RequestUriProcessor.CreateUriParserWithBatchReferenceCallback(service, service.OperationContext.AbsoluteRequestUri);
        }
Exemplo n.º 5
0
 /// <summary>Initializes a new EntitySerializer instance.</summary>
 /// <param name="requestDescription">Request description.</param>
 /// <param name="absoluteServiceUri">Absolute URI to the service entry point.</param>
 /// <param name="service">Service with configuration and provider from which metadata should be gathered.</param>
 /// <param name="httpETagHeaderValue">HTTP ETag header value.</param>
 /// <param name="messageWriter">ODataMessageWriter instance which needs to be used to write the response.</param>
 /// <param name="contentFormat">The content format.</param>
 internal EntitySerializer(
     RequestDescription requestDescription,
     Uri absoluteServiceUri,
     IDataService service,
     string httpETagHeaderValue,
     ODataMessageWriter messageWriter,
     ODataFormat contentFormat)
     : base(requestDescription, absoluteServiceUri, service, httpETagHeaderValue)
 {
     Debug.Assert(service != null, "service != null");
     this.messageWriter = messageWriter;
     this.contentFormat = contentFormat;
 }
        /// <summary>Initializes a new SyndicationSerializer instance.</summary>
        /// <param name="requestDescription">Description of request.</param>
        /// <param name="absoluteServiceUri">Base URI from which resources should be resolved.</param>
        /// <param name="service">Service with configuration and provider from which metadata should be gathered.</param>
        /// <param name="output">Output stream.</param>
        /// <param name="encoding">Encoding for output.</param>
        internal PlainXmlSerializer(
            RequestDescription requestDescription,
            Uri absoluteServiceUri,
            IDataService service,
            Stream output, 
            Encoding encoding)
            : base(requestDescription, absoluteServiceUri, service, null)
        {
            Debug.Assert(output != null, "output != null");
            Debug.Assert(encoding != null, "encoding != null");

            this.writer = XmlUtil.CreateXmlWriterAndWriteProcessingInstruction(output, encoding);
        }
        /// <summary>
        /// Initializes a new <see cref="JsonSerializer"/>, ready to write out a description.
        /// </summary>
        /// <param name="requestDescription">Description for the requested results.</param>
        /// <param name="output">Stream to which output should be sent.</param>
        /// <param name="absoluteServiceUri">Absolute URI to the service entry point.</param>
        /// <param name="service">Service with configuration and provider from which metadata should be gathered.</param>
        /// <param name="encoding">Text encoding for the response.</param>
        /// <param name="httpETagHeaderValue">HTTP ETag header value.</param>
        internal JsonSerializer(
            RequestDescription requestDescription, 
            Stream output, 
            Uri absoluteServiceUri,
            IDataService service,
            Encoding encoding,
            string httpETagHeaderValue)
            : base(requestDescription, absoluteServiceUri, service, httpETagHeaderValue)
        {
            Debug.Assert(output != null, "output != null");
            Debug.Assert(encoding != null, "encoding != null");

            this.writer = new JsonWriter(new StreamWriter(output, encoding));
        }
        /// <summary>
        /// Initializes a new instance of <see cref="ODataMessageReaderDeserializer"/>.
        /// </summary>
        /// <param name="update">true if we're reading an update operation; false if not.</param>
        /// <param name="dataService">Data service for which the deserializer will act.</param>
        /// <param name="tracker">Tracker to use for modifications.</param>
        /// <param name="requestDescription">The request description to use.</param>
        /// <param name="enableODataServerBehavior">If true, the message reader settings will use the ODataServer behavior;
        /// if false, the message reader settings will use the default behavior.</param>
        internal ODataMessageReaderDeserializer(bool update, IDataService dataService, UpdateTracker tracker, RequestDescription requestDescription, bool enableODataServerBehavior)
            : base(update, dataService, tracker, requestDescription)
        {
            AstoriaRequestMessage requestMessage = dataService.OperationContext.RequestMessage;

            // WCF DS needs to treat content type */* as ATOM payload, so check for it here and override the content type header
            if (ContentTypeUtil.CompareMimeType(requestMessage.ContentType, XmlConstants.MimeAny))
            {
                requestMessage.ContentType = XmlConstants.MimeApplicationAtom;
            }

            this.messageReader = new ODataMessageReader(
                requestMessage,
                WebUtil.CreateMessageReaderSettings(dataService, enableODataServerBehavior),
                dataService.Provider.GetMetadataProviderEdmModel());
        }
        /// <summary>Initializes a new SyndicationSerializer instance.</summary>
        /// <param name="requestDescription">Request description.</param>
        /// <param name="absoluteServiceUri">Absolute URI to the service entry point.</param>
        /// <param name="service">Service with configuration and provider from which metadata should be gathered.</param>
        /// <param name="output">Stream to write to.</param>
        /// <param name="encoding">Encoding for text in output stream.</param>
        /// <param name="etag">HTTP ETag header value.</param>
        /// <param name="factory">Factory for formatter objects.</param>
        internal SyndicationSerializer(
            RequestDescription requestDescription,
            Uri absoluteServiceUri,
            IDataService service,
            Stream output,
            Encoding encoding,
            string etag,
            SyndicationFormatterFactory factory)
            : base(requestDescription, absoluteServiceUri, service, etag)
        {
            Debug.Assert(service != null, "service != null");
            Debug.Assert(output != null, "output != null");
            Debug.Assert(encoding != null, "encoding != null");
            Debug.Assert(factory != null, "factory != null");

            this.factory = factory;
            this.writer = factory.CreateWriter(output, encoding);
        }
        public AddToCacheResult AddRequestToInfiniteCache(RequestDescription request, double cachingScore)
        {
            if (Cache.VideoCache.ContainsKey(request.VideoID))
            {
                Cache.VideoCache[request.VideoID].CacheScore += cachingScore;
            }
            else
            {
                Cache.VideoCache.Add(request.VideoID, new CachedVideoRequest
                {
                    Video           = request.Video,
                    VideoID         = request.VideoID,
                    CacheScore      = cachingScore,
                    OriginalRequest = request
                });
                request.IsCached = true;
            }

            return(AddToCacheResult.Added);
        }
Exemplo n.º 11
0
        /// <summary>Sets the response status code and the default caching and versioning headers.</summary>
        /// <param name="description">The request description for the current request.</param>
        /// <param name="statusCode">The status code for the response.</param>
        internal void SetResponseHeaders(RequestDescription description, int statusCode)
        {
            // Set the caching policy appropriately - for the time being, we disable caching.
            this.SetHeader(XmlConstants.HttpResponseCacheControl, XmlConstants.HttpCacheControlNoCache);

            // If a preference was applied, add corresponding response header.
            ClientPreference preference = description.Preference;

            this.PreferenceAppliedHeader().ReturnContent = preference.ShouldIncludeResponseBody ? true : (preference.ShouldNotIncludeResponseBody ? (bool?)false : null);

            // Only set the annotation filter to the Preference-Applied if we are writing a response body
            // since instance annotations only appear in the response body.
            if (description.ShouldWriteResponseBody && !string.IsNullOrEmpty(preference.AnnotationFilter))
            {
                this.PreferenceAppliedHeader().AnnotationFilter = preference.AnnotationFilter;
            }

            this.SetHeader(XmlConstants.HttpODataVersion, description.ResponseVersion.ToString() + ";");
            this.StatusCode = statusCode;
        }
        public void TokenSecretNotIncludedInAuthorizationHeaderForPostRequestWithUseAuthorizationHeaders()
        {
            var session = new OAuthSession(new OAuthConsumerContext {
                ConsumerKey = "consumer", UseHeaderForOAuthParameters = true
            }, "http://localhost/request",
                                           "http://localhost/userauth", "http://localhost/access", null);

            var accessToken = new TokenBase {
                ConsumerKey = "consumer", Token = "token", TokenSecret = "secret"
            };

            RequestDescription description = session
                                             .Request(accessToken)
                                             .Post()
                                             .ForUrl("http://localhost/")
                                             .SignWithToken()
                                             .GetRequestDescription();

            Assert.False(description.Headers["Authorization"].Contains(Parameters.OAuth_Token_Secret));
        }
        public void TokenSecretNotIncludedInQueryParametersForGetRequest()
        {
            var session = new OAuthSession(new OAuthConsumerContext {
                ConsumerKey = "consumer"
            }, "http://localhost/request",
                                           "http://localhost/userauth", "http://localhost/access", null);

            var accessToken = new TokenBase {
                ConsumerKey = "consumer", Token = "token", TokenSecret = "secret"
            };

            RequestDescription description = session
                                             .Request(accessToken)
                                             .Get()
                                             .ForUrl("http://localhost/")
                                             .SignWithToken()
                                             .GetRequestDescription();

            Assert.False(description.Url.ToString().Contains(Parameters.OAuth_Token_Secret));
        }
Exemplo n.º 14
0
        /// <summary>Filters a query like a SQL WHERE clause does.</summary>
        /// <param name="service">Service with data and configuration.</param>
        /// <param name="requestDescription">RequestDescription instance containing information about the current request being parsed.</param>
        /// <param name="source">Original source for query expression.</param>
        /// <returns>The composed query expression.</returns>
        internal static Expression Where(IDataService service, RequestDescription requestDescription, Expression source)
        {
            Debug.Assert(service != null, "service != null");
            Debug.Assert(source != null, "source != null");
            Debug.Assert(requestDescription != null, "requestDescription != null");

            FilterClause filterClause = new RequestExpressionParser(service, requestDescription).ParseFilter();

            if (filterClause == null)
            {
                return source;
            }

            bool filterQueryApplicable = requestDescription.TargetKind == RequestTargetKind.Resource
                                         || requestDescription.TargetKind == RequestTargetKind.OpenProperty
                                         || requestDescription.TargetKind == RequestTargetKind.ComplexObject
                                         || requestDescription.CountOption == RequestQueryCountOption.CountSegment;

            if (!filterQueryApplicable)
            {
                throw DataServiceException.CreateBadRequestError(Strings.RequestQueryProcessor_QueryFilterOptionNotApplicable);
            }

            Type queryElementType = source.ElementType();
            Debug.Assert(queryElementType != null, "queryElementType != null");

            ParameterExpression parameterForIt = Expression.Parameter(queryElementType, "it");
            Debug.Assert(
                (requestDescription.TargetResourceSet == null && (requestDescription.TargetResourceType == null || requestDescription.TargetResourceType.ResourceTypeKind != ResourceTypeKind.EntityType)) ||
                (requestDescription.TargetResourceType != null && requestDescription.TargetResourceType.ResourceTypeKind == ResourceTypeKind.EntityType),
                "setForIt cannot be null if typeForIt is an entity type.");
            Debug.Assert(
                requestDescription.TargetResourceType == null && parameterForIt.Type == typeof(object) ||
                requestDescription.TargetResourceType != null && requestDescription.TargetResourceType.InstanceType == parameterForIt.Type,
                "non-open type expressions should have a typeForIt");

            var translator = NodeToExpressionTranslator.Create(service, requestDescription, parameterForIt);
            LambdaExpression lambda = translator.TranslateFilterClause(filterClause);
            return source.QueryableWhere(lambda);
        }
Exemplo n.º 15
0
        /// <summary>
        /// Sets a resource reference to resource referenced by a URL.
        /// </summary>
        /// <param name="entityResource">The entity resource to set the resource reference on.</param>
        /// <param name="navigationProperty">The navigation property for which to set the reference to null.</param>
        /// <param name="url">The URL which points to the resource to set as the value of the navigation property.</param>
        private void SetResourceReferenceToUrl(object entityResource, ResourceProperty navigationProperty, string url)
        {
            Debug.Assert(entityResource != null, "entityResource != null");
            Debug.Assert(navigationProperty != null, "navigationProperty != null");

            // Update the object count when you are performing a bind operation.
            this.CheckAndIncrementObjectCount();

            // Get the referenced resource.
            Uri referencedUri = RequestUriProcessor.GetAbsoluteUriFromReference(url, this.Service.OperationContext);
            RequestDescription requestDescription = RequestUriProcessor.ProcessRequestUri(referencedUri, this.Service, true /*internalQuery*/);

            // ATOM deserializer checks that the url doesn't point to a collection. If it does it will ignore the link.
            if (this.IsAtomRequest && !requestDescription.IsSingleResult)
            {
                if (navigationProperty != null &&
                    navigationProperty.Kind == ResourcePropertyKind.ResourceReference)
                {
                    throw DataServiceException.CreateBadRequestError(Microsoft.OData.Service.Strings.BadRequest_LinkHrefMustReferToSingleResource(navigationProperty.Name));
                }

                return;
            }

            // Get the resource
            object referencedResource = this.Service.GetResource(requestDescription, requestDescription.SegmentInfos.Count - 1, null);

            if (navigationProperty.Kind == ResourcePropertyKind.ResourceReference)
            {
                this.Updatable.SetReference(entityResource, navigationProperty.Name, referencedResource);
            }
            else
            {
                Debug.Assert(navigationProperty.Kind == ResourcePropertyKind.ResourceSetReference, "Only navigation properties are allowed in this method.");

                // If we are to set the resource to a collection property it must not be null (so check for nulls), otherwise do allow nulls for backward compatibility.
                WebUtil.CheckResourceExists(referencedResource != null, requestDescription.LastSegmentInfo.Identifier);
                this.Updatable.AddReferenceToCollection(entityResource, navigationProperty.Name, referencedResource);
            }
        }
Exemplo n.º 16
0
        /// <summary>
        /// Binds the expand paths from the requests $expand query option to the sets/types/properties from the metadata provider of the service.
        /// </summary>
        /// <param name="requestDescription">The request description.</param>
        /// <param name="dataService">The data service.</param>
        /// <param name="expandQueryOption">The value of the $expand query option.</param>
        /// <returns>The bound expand segments.</returns>
        internal static IList <IList <ExpandItem> > BindExpandSegments(RequestDescription requestDescription, IDataService dataService, string expandQueryOption)
        {
            Debug.Assert(requestDescription != null, "requestDescription != null");
            Debug.Assert(dataService != null, "dataService != null");

            if (string.IsNullOrWhiteSpace(expandQueryOption))
            {
                return(new List <IList <ExpandItem> >());
            }

            ResourceType       targetResourceType = requestDescription.TargetResourceType;
            ResourceSetWrapper targetResourceSet  = requestDescription.TargetResourceSet;

            if (targetResourceType == null || targetResourceType.ResourceTypeKind != ResourceTypeKind.EntityType || targetResourceSet == null)
            {
                throw DataServiceException.CreateBadRequestError(Strings.RequestQueryProcessor_QueryExpandOptionNotApplicable);
            }

            MetadataProviderEdmModel model      = dataService.Provider.GetMetadataProviderEdmModel();
            IEdmEntityType           targetType = (IEdmEntityType)model.EnsureSchemaType(targetResourceType);
            IEdmEntitySet            targetSet  = model.EnsureEntitySet(targetResourceSet);

            SelectExpandClause clause;

            try
            {
                model.Mode = MetadataProviderEdmModelMode.SelectAndExpandParsing;
                clause     = ODataUriParser.ParseSelectAndExpand(/*select*/ null, expandQueryOption, model, targetType, targetSet);
            }
            catch (ODataException ex)
            {
                throw new DataServiceException(400, null, ex.Message, null, ex);
            }
            finally
            {
                model.Mode = MetadataProviderEdmModelMode.Serialization;
            }

            return(new ExpandAndSelectPathExtractor(clause).ExpandPaths);
        }
Exemplo n.º 17
0
		public void generate_request_with_raw_body_includes_body_hash()
		{
			var session = new OAuthSession(new OAuthConsumerContext {ConsumerKey = "consumer", UseHeaderForOAuthParameters = true}, "http://localhost/request", "http://localhost/userauth",
			                               "http://localhost/access");

			var accessToken = new TokenBase {ConsumerKey = "consumer", Token = "token", TokenSecret = "secret"};

			byte[] rawContents = Encoding.UTF8.GetBytes("Hello World!");

			IConsumerRequest content = session
				.EnableOAuthRequestBodyHashes()
				.Request(accessToken)
				.Post()
				.ForUrl("http://localhost/resource")
				.WithRawContent(rawContents);

			RequestDescription description = content.GetRequestDescription();

			Assert.Equal(rawContents, description.RawBody);

			Assert.Contains("oauth_body_hash=\"Lve95gjOVATpfV8EL5X4nxwjKHE%3D\"", description.Headers[Parameters.OAuth_Authorization_Header]);
		}
Exemplo n.º 18
0
        internal static IEnumerator GetSingleResultFromRequest(SegmentInfo segmentInfo)
        {
            IEnumerator enumerator2;
            IEnumerator requestEnumerator = WebUtil.GetRequestEnumerator(segmentInfo.RequestEnumerable);
            bool        flag = true;

            try
            {
                WebUtil.CheckResourceExists(requestEnumerator.MoveNext(), segmentInfo.Identifier);
                RequestDescription.CheckNullDirectReference(requestEnumerator.Current, segmentInfo);
                flag        = false;
                enumerator2 = requestEnumerator;
            }
            finally
            {
                if (flag)
                {
                    WebUtil.Dispose(requestEnumerator);
                }
            }
            return(enumerator2);
        }
Exemplo n.º 19
0
        private MessageWriterBuilder ForNormalRequest()
        {
            var requestDescription = new RequestDescription(RequestTargetKind.Resource, RequestTargetSource.EntitySet, new Uri("http://temp.org/"));

            var resourceType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Fake", "Type", false)
            {
                CanReflectOnInstanceType = false, IsOpenType = true
            };

            resourceType.AddProperty(new ResourceProperty("Id", ResourcePropertyKind.Key | ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(int)))
            {
                CanReflectOnInstanceTypeProperty = false
            });
            var resourceSet = new ResourceSet("FakeSet", resourceType);

            resourceSet.SetReadOnly();

            requestDescription.LastSegmentInfo.TargetResourceType = resourceType;
            requestDescription.LastSegmentInfo.TargetResourceSet  = ResourceSetWrapper.CreateForTests(resourceSet);

            return(this.ForNormalRequest(requestDescription));
        }
Exemplo n.º 20
0
        public void RawValueWithMimeTypeShouldUseFormat()
        {
            this.host.AbsoluteServiceUri = new Uri("http://myservice.org/");
            this.host.AbsoluteRequestUri = new Uri("http://myservice.org/FakeSet");

            SegmentInfo segment = new SegmentInfo
            {
                TargetKind        = RequestTargetKind.PrimitiveValue,
                TargetSource      = RequestTargetSource.Property,
                ProjectedProperty = new ResourceProperty("Fake", ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(string)))
                {
                    MimeType = "fake/things"
                }
            };

            var requestDescription = new RequestDescription(new[] { segment }, new Uri("http://temp.org"));

            var testSubject = this.ForNormalRequest(requestDescription);

            testSubject.WriterSettings.UseFormat.Should().BeTrue();
            testSubject.WriterSettings.Format.Should().BeSameAs(ODataFormat.RawValue);
        }
Exemplo n.º 21
0
        //Launched when user clicks Get Sheets from Home view
        public ActionResult Start()
        {
            try
            {
                //From DevDefined library
                //Makes initial GET request to Smartsheet to display the authentication screen
                OAuthSession session = BuildSession();

                RequestDescription requestTokenRequest = session
                                                         .BuildRequestTokenContext("GET")
                                                         .GetRequestDescription();
                ViewBag.logout = false;

                return(new RedirectResult(requestTokenRequest.Url.OriginalString));
            }

            catch (WebException e)
            {
                //Stores the error message to the ViewBag so it can be displayed in the Failure view
                ViewBag.error = e.Message;
                return(View("Failure"));
            }
        }
        public AddToCacheResult AddRequestToCache(RequestDescription request, double cachingScore)
        {
            if (request.Video.VideoSizeInMb > (MaxMb - ConsumedSpace))
            {
                return(AddToCacheResult.NotEnoughFreeSpace);
            }

            if (Cache.VideoCache.ContainsKey(request.VideoID))
            {
                Cache.VideoCache[request.VideoID].CacheScore += cachingScore;
            }
            else
            {
                Cache.VideoCache.Add(request.VideoID, new CachedVideoRequest
                {
                    Video      = request.Video,
                    VideoID    = request.VideoID,
                    CacheScore = cachingScore
                });
            }

            return(AddToCacheResult.Added);
        }
Exemplo n.º 23
0
        public async Task <AsyncReadResult <TValue> > ReadAsync(TKey key)
        {
            var innerData = await _api.ReadAsync(key);

            TValue data = default(TValue);

            if (innerData == null || innerData.Transaction == null || innerData.Transaction.UserTransaction == null)
            {
                return(new AsyncReadResult <TValue>(new RequestDescription(Errors.FailRead), data));
            }

            var result = new RequestDescription(innerData.Transaction.UserTransaction);

            if (innerData.Data != null)
            {
                data = _dataProvider.DeserializeValue(innerData.Data);
            }
            else
            {
                result.DataNotFound();
            }

            return(new AsyncReadResult <TValue>(result, data));
        }
Exemplo n.º 24
0
        /// <summary>
        /// Returns the index of the entity that need to get modified
        /// </summary>
        /// <param name="description">description about the target request</param>
        /// <returns>Returns the index of the entity that needs to get modified</returns>
        internal static int GetIndexOfEntityResourceToModify(RequestDescription description)
        {
            Debug.Assert(description.TargetSource == RequestTargetSource.Property, "description.TargetSource == RequestTargetSource.Property");

            int entityResourceIndex = -1;
            if (description.LinkUri)
            {
                Debug.Assert(
                    description.SegmentInfos[description.SegmentInfos.Count - 2].TargetKind == RequestTargetKind.Link,
                    "There should be only one segment allowed after $ref");

                Debug.Assert(
                    description.SegmentInfos[description.SegmentInfos.Count - 3].TargetKind == RequestTargetKind.Resource && description.SegmentInfos[description.SegmentInfos.Count - 3].SingleResult,
                    "The segment previous to the $ref segment must refer to a single resource");

                entityResourceIndex = description.SegmentInfos.Count - 3;
            }
            else
            {
                for (int j = description.SegmentInfos.Count - 1; j >= 0; j--)
                {
                    if (description.SegmentInfos[j].TargetKind == RequestTargetKind.Resource && description.SegmentInfos[j].SingleResult)
                    {
                        entityResourceIndex = j;
                        break;
                    }
                }
            }

            Debug.Assert(entityResourceIndex != -1, "This method should never be called for request that doesn't have a parent resource");
            return entityResourceIndex;
        }
 internal ODataMessageReaderDeserializer(bool update, IDataService dataService, UpdateTracker tracker, RequestDescription requestDescription, bool enableWcfDataServicesServerBehavior) : base(update, dataService, tracker, requestDescription)
 {
     System.Data.Services.ODataRequestMessage requestMessage = new System.Data.Services.ODataRequestMessage(dataService.OperationContext.Host);
     if (WebUtil.CompareMimeType(requestMessage.ContentType, "*/*"))
     {
         requestMessage.ContentType = "application/atom+xml";
     }
     this.messageReader = new ODataMessageReader(requestMessage, WebUtil.CreateMessageReaderSettings(dataService, enableWcfDataServicesServerBehavior), dataService.Provider.GetMetadataModel(base.Service.OperationContext));
     this.contentFormat = System.Data.Services.ContentFormat.Unknown;
 }
Exemplo n.º 26
0
 public static ResourceProperty GetPropertyForPropertyOnlyOperation(this RequestDescription requestDescription)
 {
     return(requestDescription.GetAnnotation <ResourceProperty>(PropertyForPropertyOnlyOperationName));
 }
Exemplo n.º 27
0
 public static void SetPostServiceOperation(this RequestDescription requestDescription)
 {
     requestDescription.SetAnnotation(PostServiceOperationName, true);
 }
Exemplo n.º 28
0
        /// <summary>
        /// Returns true if we need to query the provider before updating.
        /// </summary>
        /// <param name="requestDescription">request description</param>
        /// <param name="requestValue">value corresponding to the payload for this request</param>
        /// <param name="provider">provider against which the request was targeted</param>
        /// <returns>returns true if we need to issue an query to satishfy the request</returns>
        private static bool IsQueryRequired(RequestDescription requestDescription, object requestValue, DataServiceProviderWrapper provider)
        {
            Debug.Assert(requestDescription.IsSingleResult, "requestDescription.IsSingleResult");

            if (requestDescription.TargetKind == RequestTargetKind.PrimitiveValue ||
                requestDescription.TargetKind == RequestTargetKind.Primitive ||
                requestDescription.TargetKind == RequestTargetKind.OpenPropertyValue ||
                requestDescription.TargetKind == RequestTargetKind.MediaResource ||
                requestDescription.TargetKind == RequestTargetKind.ComplexObject)
            {
                return true;
            }

            if (requestDescription.TargetKind == RequestTargetKind.OpenProperty)
            {
                Debug.Assert(!requestDescription.LastSegmentInfo.HasKeyValues, "CreateSegments must have caught this issue.");
                
                // if the value is null, then just set it, since we don't know the type
                if (requestValue == null || WebUtil.IsPrimitiveType(requestValue.GetType()))
                {
                    return true;
                }

                // otherwise just set the complex type properties
                if (WebUtil.GetNonPrimitiveResourceType(provider, requestValue).ResourceTypeKind == ResourceTypeKind.ComplexType)
                {
                    return true;
                }
            }

            return false;
        }
Exemplo n.º 29
0
 public static bool GetInvalidClientRequest(this RequestDescription requestDescription)
 {
     return(requestDescription.GetAnnotation <bool?>(InvalidClientRequestAnnotationName) == true);
 }
Exemplo n.º 30
0
        /// <summary>
        /// Returns the entity that need to get modified
        /// </summary>
        /// <param name="description">description about the target request</param>
        /// <param name="service">data service type to which the request was made</param>
        /// <param name="allowCrossReferencing">whether cross-referencing is allowed for the resource in question.</param>
        /// <param name="entityContainer">entity container of the entity which is getting modified.</param>
        /// <param name="entityResourceIndex">index of the segment which refers to the entity getting modified.</param>
        /// <returns>Returns the entity that needs to get modified</returns>
        private static object GetEntityResourceToModify(
           RequestDescription description,
           IDataService service,
           bool allowCrossReferencing,
           out ResourceSetWrapper entityContainer,
           out int entityResourceIndex)
        {
            Debug.Assert(description.SegmentInfos.Count >= 2, "description.SegmentInfos.Count >= 2");

            if (!allowCrossReferencing && description.RequestExpression == null)
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequest_ResourceCanBeCrossReferencedOnlyForBindOperation);
            }

            // Get the index of the entity resource that is getting modified
            entityResourceIndex = Deserializer.GetIndexOfEntityResourceToModify(description);
            Debug.Assert(entityResourceIndex != -1, "This method should never be called for request that doesn't have a parent resource");
            entityContainer = description.SegmentInfos[entityResourceIndex].TargetResourceSet;
            Debug.Assert(entityContainer != null, "Entity container cannot be null for segments whose targetkind is resource");

            AstoriaRequestMessage host = service.OperationContext.RequestMessage;

            // Since this is the entity which is going to get modified, then we need to check for rights
            if (host.HttpVerb == HttpVerbs.PUT)
            {
                DataServiceConfiguration.CheckResourceRights(entityContainer, EntitySetRights.WriteReplace);
            }
            else if (host.HttpVerb == HttpVerbs.PATCH)
            {
                DataServiceConfiguration.CheckResourceRights(entityContainer, EntitySetRights.WriteMerge);
            }
            else
            {
                Debug.Assert(
                    host.HttpVerb == HttpVerbs.POST ||
                    host.HttpVerb == HttpVerbs.DELETE,
                    "expecting POST and DELETE methods");
                DataServiceConfiguration.CheckResourceRights(entityContainer, EntitySetRights.WriteMerge | EntitySetRights.WriteReplace);
            }

            object entityResource = service.GetResource(description, entityResourceIndex, null);
            if (entityResource == null)
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequest_DereferencingNullPropertyValue(description.SegmentInfos[entityResourceIndex].Identifier));
            }

            return entityResource;
        }
Exemplo n.º 31
0
        /// <summary>
        /// Handle bind operation
        /// </summary>
        /// <param name="description">information about the request uri.</param>
        /// <param name="linkResource">the child resource which needs to be linked.</param>
        /// <param name="service">data service instance</param>
        /// <param name="tracker">update tracker instance to fire change interceptor calls</param>
        /// <returns>returns the parent object to which an new object was linked to.</returns>
        internal static object HandleBindOperation(RequestDescription description, object linkResource, IDataService service, UpdateTracker tracker)
        {
            Debug.Assert(description != null, "description != null");
            Debug.Assert(linkResource != null, "linkResource != null");
            Debug.Assert(service != null, "service != null");
            Debug.Assert(tracker != null, "tracker != null");

            ResourceSetWrapper container;
            object entityGettingModified = Deserializer.GetEntityResourceToModify(description, service, true /*allowCrossReference*/, out container);

            tracker.TrackAction(entityGettingModified, container, UpdateOperations.Change);
            Debug.Assert(description.Property != null, "description.Property != null");
            if (description.IsSingleResult)
            {
                service.Updatable.SetReference(entityGettingModified, description.Property.Name, linkResource);
            }
            else
            {
                service.Updatable.AddReferenceToCollection(entityGettingModified, description.Property.Name, linkResource);
            }

            return entityGettingModified;
        }
Exemplo n.º 32
0
        /// <summary>
        /// Returns the last segment info whose target request kind is resource
        /// </summary>
        /// <param name="description">description about the target request</param>
        /// <param name="service">data service type to which the request was made</param>
        /// <param name="allowCrossReferencing">whether cross-referencing is allowed for the resource in question.</param>
        /// <param name="entityResource">entity resource which is getting modified.</param>
        /// <param name="entityContainer">entity container of the entity which is getting modified.</param>
        /// <param name="checkETag">whether to check the etag for the entity resource that is getting modified.</param>
        /// <returns>Returns the object that needs to get modified</returns>
        internal static object GetResourceToModify(
            RequestDescription description,
            IDataService service,
            bool allowCrossReferencing,
            out object entityResource,
            out ResourceSetWrapper entityContainer,
            bool checkETag)
        {
            // Set the index of the modifying resource
            int modifyingResourceIndex;
            if (
                description.TargetKind == RequestTargetKind.OpenPropertyValue ||
                description.TargetKind == RequestTargetKind.PrimitiveValue)
            {
                modifyingResourceIndex = description.SegmentInfos.Count - 3;
            }
            else
            {
                modifyingResourceIndex = description.SegmentInfos.Count - 2;
            }

            int entityResourceIndex;
            entityResource = Deserializer.GetEntityResourceToModify(
                description,
                service,
                allowCrossReferencing,
                out entityContainer,
                out entityResourceIndex);

            // now walk from the entity resource to the resource to modify.
            // for open types, as you walk, if the intermediate resource is an entity,
            // update the entityResource accordingly.
            object resourceToModify = entityResource;
            for (int i = entityResourceIndex + 1; i <= modifyingResourceIndex; i++)
            {
                // If the segment is a type identifier segment, skip the segment. There is no need to issue one more query
                // to the provider.
                if (description.SegmentInfos[i].IsTypeIdentifierSegment)
                {
                    continue;
                }

#if DEBUG
                SegmentInfo segmentInfo = description.SegmentInfos[i];
                Debug.Assert(segmentInfo.TargetKind != RequestTargetKind.Resource, "segmentInfo.TargetKind != RequestTargetKind.Resource");
#endif
                resourceToModify = service.Updatable.GetValue(resourceToModify, description.SegmentInfos[i].Identifier);
            }

            // If checkETag is true, then we need to check the etag for the resource
            // Note that MediaResource has a separate etag, we don't need to check the MLE etag if the target kind is MediaResource
            if (checkETag && !WebUtil.IsCrossReferencedSegment(description.SegmentInfos[modifyingResourceIndex], service) && description.TargetKind != RequestTargetKind.MediaResource)
            {
                service.Updatable.SetETagValues(entityResource, entityContainer);
            }

            return resourceToModify;
        }
Exemplo n.º 33
0
        internal static Deserializer CreateDeserializer(RequestDescription description, IDataService dataService, bool update, UpdateTracker tracker)
        {
            string mimeType;
            System.Text.Encoding encoding;
            AstoriaRequestMessage host = dataService.OperationContext.RequestMessage;
            ContentTypeUtil.ReadContentType(host.ContentType, out mimeType, out encoding);
            Debug.Assert(tracker != null, "Change tracker must always be created.");

            Debug.Assert(
                (!update /*POST*/ && dataService.OperationContext.RequestMessage.HttpVerb == HttpVerbs.POST) ||
                (update /*PUT,PATCH*/ && (dataService.OperationContext.RequestMessage.HttpVerb == HttpVerbs.PUT || 
                    dataService.OperationContext.RequestMessage.HttpVerb == HttpVerbs.PATCH)),
                "For PUT and PATCH, update must be true; for POST, update must be false");

            if (description.IsServiceActionRequest)
            {
                return new ParameterDeserializer(update, dataService, tracker, description);
            }

            if (description.TargetKind == RequestTargetKind.OpenPropertyValue ||
                description.TargetKind == RequestTargetKind.PrimitiveValue)
            {
                return new RawValueDeserializer(update, dataService, tracker, description);
            }

            if (description.TargetKind == RequestTargetKind.MediaResource)
            {
                return new MediaResourceDeserializer(update, dataService, tracker, description);
            }

            if (description.TargetKind == RequestTargetKind.Primitive ||
                description.TargetKind == RequestTargetKind.ComplexObject ||
                description.TargetKind == RequestTargetKind.Collection ||
                description.TargetKind == RequestTargetKind.OpenProperty)
            {
                return new PropertyDeserializer(update, dataService, tracker, description);
            }

            if (description.LinkUri)
            {
                return new EntityReferenceLinkDeserializer(update, dataService, tracker, description);
            }

            if (description.TargetKind == RequestTargetKind.Resource)
            {
                return new EntityDeserializer(update, dataService, tracker, description);
            }

            throw new DataServiceException(415, Strings.RequestUriProcessor_MethodNotAllowed);
        }
Exemplo n.º 34
0
 /// <summary>
 /// Returns the entity that need to get modified
 /// </summary>
 /// <param name="description">description about the target request</param>
 /// <param name="service">data service type to which the request was made</param>
 /// <param name="allowCrossReferencing">whether cross-referencing is allowed for the resource in question.</param>
 /// <param name="entityContainer">entity container of the entity which is getting modified.</param>
 /// <returns>Returns the entity that needs to get modified</returns>
 internal static object GetEntityResourceToModify(
     RequestDescription description,
     IDataService service,
     bool allowCrossReferencing,
     out ResourceSetWrapper entityContainer)
 {
     int entityResourceIndex;
     return Deserializer.GetEntityResourceToModify(
         description,
         service,
         allowCrossReferencing,
         out entityContainer,
         out entityResourceIndex);
 }
Exemplo n.º 35
0
        /// <summary>
        /// Modify the value of the given resource to the given value
        /// </summary>
        /// <param name="description">description about the request</param>
        /// <param name="resourceToBeModified">resource that needs to be modified</param>
        /// <param name="requestValue">the new value for the target resource</param>
        /// <param name="service">Service this request is against</param>
        internal static void ModifyResource(RequestDescription description, object resourceToBeModified, object requestValue, IDataService service)
        {
            if (description.TargetKind == RequestTargetKind.OpenProperty ||
                description.TargetKind == RequestTargetKind.OpenPropertyValue)
            {
                Debug.Assert(!description.LastSegmentInfo.HasKeyValues, "CreateSegments must have caught the problem already.");
                SetOpenPropertyValue(resourceToBeModified, description.ContainerName, requestValue, service);
            }
            else if (description.TargetKind == RequestTargetKind.MediaResource)
            {
                SetStreamPropertyValue(resourceToBeModified, (Stream)requestValue, service, description);
            }
            else
            {
                Debug.Assert(
                    description.TargetKind == RequestTargetKind.Primitive ||
                    description.TargetKind == RequestTargetKind.ComplexObject ||
                    description.TargetKind == RequestTargetKind.PrimitiveValue ||
                    description.TargetKind == RequestTargetKind.Collection,
                    "unexpected target kind encountered");

                // update the primitive value
                ResourceProperty propertyToUpdate = description.LastSegmentInfo.ProjectedProperty;
                SetPropertyValue(propertyToUpdate, resourceToBeModified, requestValue, service);
            }
        }
Exemplo n.º 36
0
        /// <summary>
        /// Reads the action parameters from the payload.
        /// </summary>
        /// <param name="actionSegment">Segment info for the action whose parameters are being read.</param>
        /// <param name="dataService">Data service instance.</param>
        /// <returns>A dictionary of parameter name and parameter value pairs.</returns>
        internal static Dictionary<string, object> ReadPayloadParameters(SegmentInfo actionSegment, IDataService dataService)
        {
            Debug.Assert(actionSegment != null, "actionSegment != null");
            RequestDescription requestDescription = new RequestDescription(new SegmentInfo[] { actionSegment }, RequestUriProcessor.GetResultUri(dataService.OperationContext));
            Debug.Assert(requestDescription.IsServiceActionRequest, "IsServiceActionRequest(requestDescription)");

            // Verify that the DSV is 4.0 or greater for parameters payload.
            requestDescription.VerifyRequestVersion(VersionUtil.Version4Dot0, dataService);

            using (Deserializer parameterDeserializer = Deserializer.CreateDeserializer(requestDescription, dataService, false /*update*/, UpdateTracker.CreateUpdateTracker(dataService)))
            {
                return (Dictionary<string, object>)parameterDeserializer.Deserialize(actionSegment);
            }
        }
 /// <summary>
 /// Initializes a new instance of <see cref="EntityReferenceLinkDeserializer"/>.
 /// </summary>
 /// <param name="update">true if we're reading an update operation; false if not.</param>
 /// <param name="dataService">Data service for which the deserializer will act.</param>
 /// <param name="tracker">Tracker to use for modifications.</param>
 /// <param name="requestDescription">The request description to use.</param>
 internal EntityReferenceLinkDeserializer(bool update, IDataService dataService, UpdateTracker tracker, RequestDescription requestDescription)
     : base(update, dataService, tracker, requestDescription, true /*enableODataServerBehavior*/)
 {
 }
Exemplo n.º 38
0
        /// <summary>
        /// Returns true if we need to query the provider before updating.
        /// </summary>
        /// <param name="requestDescription">request description</param>
        /// <param name="requestValue">value corresponding to the payload for this request</param>
        /// <returns>returns true if we need to issue an query to satishfy the request</returns>
        private static bool IsQueryRequired(RequestDescription requestDescription, object requestValue)
        {
            Debug.Assert(requestDescription.IsSingleResult, "requestDescription.IsSingleResult");

            if (requestDescription.TargetKind == RequestTargetKind.PrimitiveValue ||
                requestDescription.TargetKind == RequestTargetKind.Primitive ||
                requestDescription.TargetKind == RequestTargetKind.OpenPropertyValue ||
                requestDescription.TargetKind == RequestTargetKind.MediaResource ||
                requestDescription.TargetKind == RequestTargetKind.ComplexObject ||
                requestDescription.TargetKind == RequestTargetKind.Collection)
            {
                return true;
            }

            if (requestDescription.TargetKind == RequestTargetKind.OpenProperty)
            {
                Debug.Assert(!requestDescription.LastSegmentInfo.HasKeyValues, "CreateSegments must have caught this issue.");
                ResourceType requestResourceType = requestDescription.LastSegmentInfo.TargetResourceType;
                
                // If this open property is collection, use resourceType in requestValue.
                var requestCollectionValue = requestValue as CollectionPropertyValueEnumerable;
                if (requestResourceType == null && requestCollectionValue != null)
                {
                    requestResourceType = requestCollectionValue.ResourceType;
                    return true;
                }

                Debug.Assert(requestValue == null || requestResourceType != null, "requestResourceType != null");

                // if the value is null, then just set it, since we don't know the type
                if (requestValue == null || requestResourceType.ResourceTypeKind == ResourceTypeKind.Primitive)
                {
                    return true;
                }

                // otherwise just set the complex type properties
                if (requestResourceType.ResourceTypeKind == ResourceTypeKind.ComplexType)
                {
                    return true;
                }
            }

            return false;
        }
Exemplo n.º 39
0
        /// <summary>
        /// Create a new instance of ODataMessageWriterSettings for normal requests.
        /// </summary>
        /// <param name="dataService">Data service instance.</param>
        /// <param name="requestDescription">The current request description.</param>
        /// <param name="responseMessage">IODataResponseMessage implementation.</param>
        /// <param name="model">The model to provide to the message writer.</param>
        /// <returns>An instance of a message writer with the appropriate settings.</returns>
        internal static MessageWriterBuilder ForNormalRequest(IDataService dataService, RequestDescription requestDescription, IODataResponseMessage responseMessage, IEdmModel model)
        {
            Debug.Assert(dataService != null, "dataService != null");
            Debug.Assert(dataService.OperationContext != null, "dataService.OperationContext != null");
            Debug.Assert(requestDescription != null, "requestDescription != null");
            Debug.Assert(dataService.OperationContext.RequestMessage != null, "dataService.OperationContext.RequestMessage != null");
            Debug.Assert(responseMessage != null, "responseMessage != null");

            Uri     serviceUri      = dataService.OperationContext.AbsoluteServiceUri;
            Version responseVersion = requestDescription.ActualResponseVersion;

            MessageWriterBuilder messageWriterBuilder = new MessageWriterBuilder(serviceUri, responseVersion, dataService, responseMessage, model);

            // ODataLib doesn't allow custom MIME types on raw values (must be text/plain for non-binary, and application/octet for binary values).
            // To maintain existing V1/V2 behavior, work around this by setting the format as RawValue (we handle conneg ourself for this, so don't make ODL do its own),
            // and then later manually override the content type header. Conneg is done by Astoria in DataService.CreateResponseBodyWriter.
            if (requestDescription.ResponsePayloadKind == ODataPayloadKind.Value && !string.IsNullOrEmpty(requestDescription.MimeType))
            {
                messageWriterBuilder.WriterSettings.SetContentType(ODataFormat.RawValue);
            }
            else
            {
                string acceptHeaderValue = dataService.OperationContext.RequestMessage.GetAcceptableContentTypes();

                // In V1/V2 we defaulted to charset=utf-8 for the response when there was no specific Accept-Charset.
                // ODataMessageWriter uses a different default in some cases depending on the media type, so we need to override that here.
                string requestAcceptCharSet = dataService.OperationContext.RequestMessage.GetRequestAcceptCharsetHeader();
                if (string.IsNullOrEmpty(requestAcceptCharSet) || requestAcceptCharSet == "*")
                {
                    requestAcceptCharSet = XmlConstants.Utf8Encoding;
                }

                messageWriterBuilder.WriterSettings.SetContentType(acceptHeaderValue, requestAcceptCharSet);
            }

            // always set the metadata document URI. ODataLib will decide whether or not to write it.
            messageWriterBuilder.WriterSettings.ODataUri = new ODataUri()
            {
                ServiceRoot     = serviceUri,
                SelectAndExpand = requestDescription.ExpandAndSelect.Clause,
                Path            = requestDescription.Path
            };

            messageWriterBuilder.WriterSettings.JsonPCallback = requestDescription.JsonPaddingFunctionName;

            return(messageWriterBuilder);
        }
Exemplo n.º 40
0
        /// <summary>
        /// Handles post request.
        /// </summary>
        /// <param name="requestDescription">description about the uri for the post operation.</param>
        /// <returns>returns the resource that is getting inserted or binded - as specified in the payload.</returns>
        internal object HandlePostRequest(RequestDescription requestDescription)
        {
            Debug.Assert(!this.Update, "This method must be called for POST operations only");
            Debug.Assert(requestDescription != null, "requestDescription != null");
            object resourceInPayload;

            if (requestDescription.LinkUri)
            {
                string uri = this.GetLinkUriFromPayload();
                resourceInPayload = this.GetTargetResourceToBind(uri, true /*checkNull*/);
                Debug.Assert(resourceInPayload != null, "link resource cannot be null");
                Deserializer.HandleBindOperation(requestDescription, resourceInPayload, this.Service, this.Tracker);
            }
            else
            {
                if (requestDescription.LastSegmentInfo.TargetContainer != null)
                {
                    DataServiceConfiguration.CheckResourceRights(requestDescription.LastSegmentInfo.TargetContainer, EntitySetRights.WriteAppend);
                }

                resourceInPayload = this.ReadEntity(requestDescription);
                if (requestDescription.TargetSource == RequestTargetSource.Property)
                {
                    Debug.Assert(requestDescription.Property.Kind == ResourcePropertyKind.ResourceSetReference, "Expecting POST resource set property");
                    Deserializer.HandleBindOperation(requestDescription, resourceInPayload, this.Service, this.Tracker);
                }
                else
                {
                    Debug.Assert(requestDescription.TargetSource == RequestTargetSource.EntitySet, "Expecting POST on entity set");
                    this.tracker.TrackAction(resourceInPayload, requestDescription.LastSegmentInfo.TargetContainer, UpdateOperations.Add);
                }
            }

            return resourceInPayload;
        }
Exemplo n.º 41
0
        /// <summary>
        /// Creates a new <see cref="Deserializer"/> for the specified stream.
        /// </summary>
        /// <param name="description">description about the request uri.</param>
        /// <param name="dataService">Data service for which the deserializer will act.</param>
        /// <param name="update">indicates whether this is a update operation or not</param>
        /// <param name="tracker">Tracker to use for modifications.</param>
        /// <returns>A new instance of <see cref="Deserializer"/>.</returns>
        internal static Deserializer CreateDeserializer(RequestDescription description, IDataService dataService, bool update, UpdateTracker tracker)
        {
            string mimeType;
            System.Text.Encoding encoding;
            DataServiceHostWrapper host = dataService.OperationContext.Host;
            HttpProcessUtility.ReadContentType(host.RequestContentType, out mimeType, out encoding);
            ContentFormat requestFormat = WebUtil.SelectRequestFormat(mimeType, description);
            Stream requestStream = host.RequestStream;
            Debug.Assert(requestStream != null, "requestStream != null");
            Debug.Assert(tracker != null, "Change tracker must always be created.");
            Deserializer deserializer = null;

            Debug.Assert(
                (!update /*POST*/ && dataService.OperationContext.Host.AstoriaHttpVerb == AstoriaVerbs.POST) ||
                (update /*PUT,MERGE*/ && (dataService.OperationContext.Host.AstoriaHttpVerb == AstoriaVerbs.MERGE || dataService.OperationContext.Host.AstoriaHttpVerb == AstoriaVerbs.PUT)),
                "For PUT and MERGE, update must be true; for POST, update must be false");

            switch (requestFormat)
            {
                case ContentFormat.Json:
                    deserializer = new JsonDeserializer(
                        requestStream,
                        encoding,
                        update,
                        dataService,
                        tracker);
                    break;
                case ContentFormat.Atom:
                    SyndicationFormatterFactory factory = new Atom10FormatterFactory();
                    deserializer = new SyndicationDeserializer(
                        requestStream,  // stream
                        encoding,       // encoding
                        dataService,    // dataService
                        update,
                        factory,
                        tracker);       // factory
                    break;
                case ContentFormat.PlainXml:
                    deserializer = new PlainXmlDeserializer(
                        requestStream,
                        encoding,
                        dataService,
                        update,
                        tracker);
                    break;
                default:
                    throw new DataServiceException(415, Strings.BadRequest_UnsupportedRequestContentType(host.RequestContentType));
            }

            Debug.Assert(deserializer != null, "deserializer != null");

            return deserializer;
        }
Exemplo n.º 42
0
        /// <summary>
        /// Deserializes the given stream into clr object as specified in the payload
        /// </summary>
        /// <param name="requestDescription">description about the target request</param>
        /// <returns>the object instance that it created and populated from the reader</returns>
        internal object ReadEntity(RequestDescription requestDescription)
        {
            Debug.Assert(requestDescription != null, "requestDescription != null");
            this.description = requestDescription;

            if (requestDescription.TargetKind == RequestTargetKind.Resource)
            {
                Debug.Assert(requestDescription.LastSegmentInfo != null, "requestDescription.LastSegmentInfo != null");
                Debug.Assert(requestDescription.LastSegmentInfo.TargetContainer != null, "requestDescription.LastSegmentInfo.TargetContainer != null");
                Debug.Assert(requestDescription.TargetResourceType != null, "requestDescription.TargetResourceType != null");
                this.RequestDescription.UpdateAndCheckEpmFeatureVersion(this.description.LastSegmentInfo.TargetContainer, this.Service);
            }

            // If the description points to a resource,
            // we need to materialize the object and return back.
            SegmentInfo segmentInfo = requestDescription.LastSegmentInfo;
            if (!this.Update)
            {
                Debug.Assert(!segmentInfo.SingleResult, "POST operation is allowed only on collections");
                SegmentInfo adjustedSegment = new SegmentInfo();
                adjustedSegment.TargetKind = segmentInfo.TargetKind;
                adjustedSegment.TargetSource = segmentInfo.TargetSource;
                adjustedSegment.SingleResult = true;
                adjustedSegment.ProjectedProperty = segmentInfo.ProjectedProperty;
                adjustedSegment.TargetResourceType = segmentInfo.TargetResourceType;
                adjustedSegment.TargetContainer = segmentInfo.TargetContainer;
                adjustedSegment.Identifier = segmentInfo.Identifier;
                segmentInfo = adjustedSegment;
            }

            return this.CreateSingleObject(segmentInfo);
        }
Exemplo n.º 43
0
 public static void SetInvalidClientRequest(this RequestDescription requestDescription)
 {
     requestDescription.SetAnnotation(InvalidClientRequestAnnotationName, true);
 }
Exemplo n.º 44
0
        /// <summary>
        /// Handle bind operation
        /// </summary>
        /// <param name="description">information about the request uri.</param>
        /// <param name="linkResource">the child resource which needs to be linked.</param>
        /// <param name="service">data service instance</param>
        /// <param name="tracker">update tracker instance to fire change interceptor calls</param>
        /// <returns>returns the parent object to which an new object was linked to.</returns>
        internal static object HandleBindOperation(RequestDescription description, object linkResource, IDataService service, UpdateTracker tracker)
        {
            Debug.Assert(description != null, "description != null");
            Debug.Assert(linkResource != null, "linkResource != null");
            Debug.Assert(service != null, "service != null");
            Debug.Assert(tracker != null, "tracker != null");

            object entityGettingModified;
            ResourceSetWrapper container;

            object resourceToBeModified = Deserializer.GetResourceToModify(description, service, true /*allowCrossReference*/, out entityGettingModified, out container, false /*checkETag*/);
            Debug.Assert(resourceToBeModified == entityGettingModified, "Since this is a link operation, modifying resource must be the entity resource");

            // If the container we are modifying contains any type with FF mapped KeepInContent=false properties, we need to raise the FeatureVersion.
            description.UpdateAndCheckEpmFeatureVersion(container, service);

            tracker.TrackAction(entityGettingModified, container, UpdateOperations.Change);
            Debug.Assert(description.Property != null, "description.Property != null");
            if (description.IsSingleResult)
            {
                service.Updatable.SetReference(entityGettingModified, description.Property.Name, linkResource);
            }
            else
            {
                service.Updatable.AddReferenceToCollection(entityGettingModified, description.Property.Name, linkResource);
            }

            return entityGettingModified;
        }
Exemplo n.º 45
0
 public static void SetPropertyForPropertyOnlyOperation(this RequestDescription requestDescription, ResourceProperty property)
 {
     requestDescription.SetAnnotation(PropertyForPropertyOnlyOperationName, property);
 }
Exemplo n.º 46
0
 public object GetResource(RequestDescription description, int segmentIndex, string typeFullName)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 47
0
 public static List <ResourceType> GetExpandedResourceTypes(this RequestDescription requestDescription)
 {
     return(requestDescription.GetAnnotation <List <ResourceType> >(ExpandedResourceTypesName));
 }
Exemplo n.º 48
0
        /// <summary>Initializes a new <see cref="ResponseBodyWriter"/> that can write the body of a response.</summary>
        /// <param name="service">Service for the request being processed.</param>
        /// <param name="queryResults">Enumerator for results.</param>
        /// <param name="requestDescription">Description of request made to the system.</param>
        /// <param name="actualResponseMessageWhoseHeadersMayBeOverridden">IODataResponseMessage instance for the response.</param>
        internal ResponseBodyWriter(
            IDataService service,
            QueryResultInfo queryResults,
            RequestDescription requestDescription,
            IODataResponseMessage actualResponseMessageWhoseHeadersMayBeOverridden)
        {
            Debug.Assert(service != null, "service != null");
            Debug.Assert(requestDescription != null, "requestDescription != null");
            Debug.Assert(actualResponseMessageWhoseHeadersMayBeOverridden != null, "actualResponseMessageWhoseHeadersMayBeOverridden != null");

            this.service            = service;
            this.queryResults       = queryResults;
            this.requestDescription = requestDescription;
            this.actualResponseMessageWhoseHeadersMayBeOverridden = actualResponseMessageWhoseHeadersMayBeOverridden;

            Debug.Assert(this.PayloadKind != ODataPayloadKind.Unsupported, "payloadKind != ODataPayloadKind.Unsupported");

            this.encoding = ContentTypeUtil.EncodingFromAcceptCharset(this.service.OperationContext.RequestMessage.GetRequestAcceptCharsetHeader());

            if (this.PayloadKind == ODataPayloadKind.Entry ||
                this.PayloadKind == ODataPayloadKind.Feed ||
                this.PayloadKind == ODataPayloadKind.Property ||
                this.PayloadKind == ODataPayloadKind.Collection ||
                this.PayloadKind == ODataPayloadKind.EntityReferenceLink ||
                this.PayloadKind == ODataPayloadKind.EntityReferenceLinks ||
                this.PayloadKind == ODataPayloadKind.Error ||
                this.PayloadKind == ODataPayloadKind.ServiceDocument ||
                this.PayloadKind == ODataPayloadKind.Parameter)
            {
                AstoriaRequestMessage requestMessage = service.OperationContext.RequestMessage;
                IODataResponseMessage responseMessageOnOperationContext = service.OperationContext.ResponseMessage;

                Version effectiveMaxResponseVersion = VersionUtil.GetEffectiveMaxResponseVersion(service.Configuration.DataServiceBehavior.MaxProtocolVersion.ToVersion(), requestMessage.RequestMaxVersion);
                bool    isEntityOrFeed = this.PayloadKind == ODataPayloadKind.Entry || this.PayloadKind == ODataPayloadKind.Feed;
                if (ContentTypeUtil.IsResponseMediaTypeJsonLight(requestMessage.GetAcceptableContentTypes(), isEntityOrFeed, effectiveMaxResponseVersion))
                {
                    // If JSON light 'wins', then bump the version to V3.
                    requestDescription.VerifyAndRaiseResponseVersion(VersionUtil.Version4Dot0, service);
                    responseMessageOnOperationContext.SetHeader(XmlConstants.HttpODataVersion, XmlConstants.ODataVersion4Dot0 + ";");
                }
            }

            if (this.requestDescription.TargetKind == RequestTargetKind.MediaResource)
            {
                Debug.Assert(this.PayloadKind == ODataPayloadKind.BinaryValue, "payloadKind == ODataPayloadKind.BinaryValue");

                // Note that GetReadStream will set the ResponseETag before it returns
                this.mediaResourceStream = service.StreamProvider.GetReadStream(
                    this.queryResults.Current,
                    this.requestDescription.StreamProperty,
                    this.service.OperationContext);
            }
            else if (this.PayloadKind != ODataPayloadKind.BinaryValue)
            {
                IEdmModel model;
                if (this.PayloadKind == ODataPayloadKind.MetadataDocument)
                {
                    model = MetadataSerializer.PrepareModelForSerialization(this.service.Provider, this.service.Configuration);
                }
                else
                {
                    model = this.GetModelFromService();
                }

                // Create the message writer using which the response needs to be written.
                this.messageWriterBuilder = MessageWriterBuilder.ForNormalRequest(
                    this.service,
                    this.requestDescription,
                    this.actualResponseMessageWhoseHeadersMayBeOverridden,
                    model);

                this.messageWriter = this.messageWriterBuilder.CreateWriter();

                try
                {
                    // Make sure all the headers are written before the method returns.
                    this.contentFormat = ODataUtils.SetHeadersForPayload(this.messageWriter, this.PayloadKind);
                }
                catch (ODataContentTypeException contentTypeException)
                {
                    throw new DataServiceException(415, null, Strings.DataServiceException_UnsupportedMediaType, null, contentTypeException);
                }

                Debug.Assert(requestDescription.ResponseFormat != null, "Response format should already have been determined.");
                Debug.Assert(ReferenceEquals(this.contentFormat, requestDescription.ResponseFormat.Format), "Response format in request description did not match format when writing.");

                if (this.PayloadKind == ODataPayloadKind.Value && !String.IsNullOrEmpty(this.requestDescription.MimeType))
                {
                    this.actualResponseMessageWhoseHeadersMayBeOverridden.SetHeader(XmlConstants.HttpContentType, this.requestDescription.MimeType);
                }

                // EPM is currently removed, but this doesn't seem to be used for EPM only. The old comment was saying:
                // In astoria, there is a bug in V1/V2 that while computing response version, we did not take
                // epm into account. Hence while creating the writer, we need to pass the RequestDescription.ActualResponseVersion
                // so that ODataLib can do the correct payload validation. But we need to write the response version without
                // the epm into the response headers because of backward-compat issue. Hence over-writing the response version
                // header with the wrong version value.
                string responseVersion = this.requestDescription.ResponseVersion.ToString() + ";";
                this.actualResponseMessageWhoseHeadersMayBeOverridden.SetHeader(XmlConstants.HttpODataVersion, responseVersion);
            }
        }
Exemplo n.º 49
0
 public static bool GetPostServiceOperation(this RequestDescription requestDescription)
 {
     return(requestDescription.GetAnnotation <bool?>(PostServiceOperationName) == true);
 }
Exemplo n.º 50
0
        /// <summary>
        /// Creates a Media Link Entry.
        /// </summary>
        /// <param name="fullTypeName">Full type name for the MLE to be created.</param>
        /// <param name="requestStream">Request stream from the host.</param>
        /// <param name="service">Service this request is against.</param>
        /// <param name="description">Description of the target request.</param>
        /// <param name="tracker">Update tracker instance to fire change interceptor calls</param>
        /// <returns>Newly created Media Link Entry.</returns>
        internal static object CreateMediaLinkEntry(string fullTypeName, Stream requestStream, IDataService service, RequestDescription description, UpdateTracker tracker)
        {
            Debug.Assert(!string.IsNullOrEmpty(fullTypeName), "!string.IsNullOrEmpty(fullTypeName)");
            Debug.Assert(requestStream != null, "requestStream != null");
            Debug.Assert(service != null, "service != null");
            Debug.Assert(description != null, "description != null");
            Debug.Assert(tracker != null, "tracker != null");

            object entity = service.Updatable.CreateResource(description.LastSegmentInfo.TargetResourceSet.Name, fullTypeName);
            tracker.TrackAction(entity, description.LastSegmentInfo.TargetResourceSet, UpdateOperations.Add);
            SetStreamPropertyValue(entity, requestStream, service, description);
            return entity;
        }
Exemplo n.º 51
0
 internal NonEntitySerializer(RequestDescription requestDescription, Uri absoluteServiceUri, IDataService service, ODataMessageWriter messageWriter) : base(requestDescription, absoluteServiceUri, service, null)
 {
     this.writer = messageWriter;
 }
Exemplo n.º 52
0
        /// <summary>
        /// Copy the contents of the request stream into the default stream of the specified entity.
        /// </summary>
        /// <param name="resourceToBeModified">Entity with the associated stream which we will write to.</param>
        /// <param name="requestStream">Request stream from the host</param>
        /// <param name="service">Service this is request is against</param>
        /// <param name="description">Description of the target request.</param>
        internal static void SetStreamPropertyValue(object resourceToBeModified, Stream requestStream, IDataService service, RequestDescription description)
        {
            Debug.Assert(resourceToBeModified != null, "resourceToBeModified != null");
            Debug.Assert(requestStream.CanRead, "requestStream.CanRead");
            Debug.Assert(service != null, "service != null");

            resourceToBeModified = service.Updatable.ResolveResource(resourceToBeModified);

            ResourceType resourceType = service.Provider.GetResourceType(resourceToBeModified);
            if (!resourceType.IsMediaLinkEntry)
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidUriForMediaResource(service.OperationContext.AbsoluteRequestUri));
            }

            if (service.OperationContext.Host.AstoriaHttpVerb == AstoriaVerbs.MERGE)
            {
                throw DataServiceException.CreateMethodNotAllowed(
                    Strings.BadRequest_InvalidUriForMergeOperation(service.OperationContext.AbsoluteRequestUri),
                    DataServiceConfiguration.GetAllowedMethods(service.Configuration, description));
            }

            using (Stream writeStream = service.StreamProvider.GetWriteStream(resourceToBeModified, service.OperationContext))
            {
                WebUtil.CopyStream(requestStream, writeStream, service.StreamProvider.StreamBufferSize);
            }
        }
Exemplo n.º 53
0
 /// <summary>
 /// Initializes a new instance of <see cref="RawValueDeserializer"/>.
 /// </summary>
 /// <param name="update">true if we're reading an update operation; false if not.</param>
 /// <param name="dataService">Data service for which the deserializer will act.</param>
 /// <param name="tracker">Tracker to use for modifications.</param>
 /// <param name="requestDescription">The request description to use.</param>
 internal RawValueDeserializer(bool update, IDataService dataService, UpdateTracker tracker, RequestDescription requestDescription)
     : base(update, dataService, tracker, requestDescription, true /*enableODataServerBehavior*/)
 {
 }
Exemplo n.º 54
0
        /// <summary>
        /// Returns the last segment info whose target request kind is resource
        /// </summary>
        /// <param name="description">description about the target request</param>
        /// <param name="service">data service type to which the request was made</param>
        /// <param name="allowCrossReferencing">whether cross-referencing is allowed for the resource in question.</param>
        /// <param name="entityResource">entity resource which is getting modified.</param>
        /// <param name="entityContainer">entity container of the entity which is getting modified.</param>
        /// <param name="checkETag">whether to check the etag for the entity resource that is getting modified.</param>
        /// <returns>Returns the object that needs to get modified</returns>
        internal static object GetResourceToModify(
            RequestDescription description,
            IDataService service,
            bool allowCrossReferencing,
            out object entityResource,
            out ResourceSetWrapper entityContainer,
            bool checkETag)
        {
            Debug.Assert(description.SegmentInfos.Length >= 2, "description.SegmentInfos.Length >= 2");

            UpdatableWrapper updatable = service.Updatable;

            if (!allowCrossReferencing && description.RequestEnumerable == null)
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequest_ResourceCanBeCrossReferencedOnlyForBindOperation);
            }

            // Set the index of the modifying resource
            int modifyingResourceIndex = -1;
            if (
                description.TargetKind == RequestTargetKind.OpenPropertyValue ||
                description.TargetKind == RequestTargetKind.PrimitiveValue)
            {
                modifyingResourceIndex = description.SegmentInfos.Length - 3;
            }
            else
            {
                modifyingResourceIndex = description.SegmentInfos.Length - 2;
            }

            // Get the index of the entity resource that is getting modified
            int entityResourceIndex = -1;
            if (description.LinkUri)
            {
                entityResourceIndex = modifyingResourceIndex;
            }
            else
            {
                for (int j = modifyingResourceIndex; j >= 0; j--)
                {
                    if (description.SegmentInfos[j].TargetKind == RequestTargetKind.Resource ||
                        description.SegmentInfos[j].HasKeyValues)
                    {
                        entityResourceIndex = j;
                        break;
                    }
                }
            }

            Debug.Assert(entityResourceIndex != -1, "This method should never be called for request that doesn't have a parent resource");
            entityContainer = description.SegmentInfos[entityResourceIndex].TargetContainer;
            if (entityContainer != null)
            {
                DataServiceHostWrapper host = service.OperationContext.Host;

                // Since this is the entity which is going to get modified, then we need to check for rights
                if (host.AstoriaHttpVerb == AstoriaVerbs.PUT)
                {
                    DataServiceConfiguration.CheckResourceRights(entityContainer, EntitySetRights.WriteReplace);
                }
                else if (host.AstoriaHttpVerb == AstoriaVerbs.MERGE)
                {
                    DataServiceConfiguration.CheckResourceRights(entityContainer, EntitySetRights.WriteMerge);
                }
                else
                {
                    Debug.Assert(
                        host.AstoriaHttpVerb == AstoriaVerbs.POST ||
                        host.AstoriaHttpVerb == AstoriaVerbs.DELETE,
                        "expecting POST and DELETE methods");
                    DataServiceConfiguration.CheckResourceRights(entityContainer, EntitySetRights.WriteMerge | EntitySetRights.WriteReplace);
                }
            }

            entityResource = service.GetResource(description, entityResourceIndex, null);
            if (entityResource == null)
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequest_DereferencingNullPropertyValue(description.SegmentInfos[entityResourceIndex].Identifier));
            }

            // now walk from the entity resource to the resource to modify.
            // for open types, as you walk, if the intermediate resource is an entity,
            // update the entityResource accordingly.
            object resourceToModify = entityResource;
            for (int i = entityResourceIndex + 1; i <= modifyingResourceIndex; i++)
            {
                resourceToModify = updatable.GetValue(resourceToModify, description.SegmentInfos[i].Identifier);
            }

            if (entityContainer == null)
            {
                Debug.Assert(
                    description.TargetKind == RequestTargetKind.OpenProperty ||
                    description.TargetKind == RequestTargetKind.OpenPropertyValue,
                    "its a open property target. Hence resource set must be null");

                // Open navigation properties are not supported on OpenTypes.
                throw DataServiceException.CreateBadRequestError(Strings.OpenNavigationPropertiesNotSupportedOnOpenTypes(description.SegmentInfos[entityResourceIndex].Identifier));
            }

            // If checkETag is true, then we need to check the etag for the resource
            // Note that MediaResource has a separate etag, we don't need to check the MLE etag if the target kind is MediaResource
            if (checkETag && !Deserializer.IsCrossReferencedSegment(description.SegmentInfos[modifyingResourceIndex], service) && description.TargetKind != RequestTargetKind.MediaResource)
            {
                service.Updatable.SetETagValues(entityResource, entityContainer);
            }

            return resourceToModify;
        }
Exemplo n.º 55
0
 public void AddRequest(RequestDescription request)
 {
     AddToAnyCache(request);
 }
Exemplo n.º 56
0
 /// <summary>
 /// Gets the resource to modify.
 /// </summary>
 /// <param name="description">description about the target request</param>
 /// <param name="service">data service type to which the request was made</param>
 /// <param name="entityResource">entity resource which is getting modified.</param>
 /// <param name="container">entity container of the entity which is getting modified.</param>
 /// <returns>Returns the object that needs to get modified</returns>
 internal static object GetResourceToModify(RequestDescription description, IDataService service, out object entityResource, out ResourceSetWrapper container)
 {
     return GetResourceToModify(description, service, false /*allowCrossReference*/, out entityResource, out container, false /*checkETag*/);
 }
Exemplo n.º 57
0
 internal MediaResourceDeserializer(bool update, IDataService dataService, UpdateTracker tracker, RequestDescription requestDescription) : base(update, dataService, tracker, requestDescription)
 {
 }
Exemplo n.º 58
0
        /// <summary>
        /// Update the resource specified in the given request description
        /// </summary>
        /// <param name="description">description about the request uri</param>
        /// <param name="dataService">data service type to which the request was made</param>
        /// <param name="stream">Stream from which request body should be read.</param>
        /// <returns>The tracked modifications.</returns>
        internal static RequestDescription HandlePutRequest(RequestDescription description, IDataService dataService, Stream stream)
        {
            Debug.Assert(stream != null, "stream != null");
            Debug.Assert(dataService != null, "dataService != null");

            object requestValue = null;
            ContentFormat requestFormat;
            object entityGettingModified = null;
            ResourceSetWrapper container = null;
            string mimeType;
            Encoding encoding;
            DataServiceHostWrapper host = dataService.OperationContext.Host;
            HttpProcessUtility.ReadContentType(host.RequestContentType, out mimeType, out encoding);

            UpdateTracker tracker = UpdateTracker.CreateUpdateTracker(dataService);
            Debug.Assert(tracker != null, "Change tracker must always be created.");

            // If its a primitive value that is getting modified, then we need to use the text or binary
            // serializer depending on the mime type
            if (description.TargetKind == RequestTargetKind.OpenPropertyValue ||
                description.TargetKind == RequestTargetKind.PrimitiveValue)
            {
                string contentType;
                requestFormat = WebUtil.GetResponseFormatForPrimitiveValue(description.TargetResourceType, out contentType);
                if (!WebUtil.CompareMimeType(contentType, mimeType))
                {
                    if (description.TargetResourceType != null)
                    {
                        throw new DataServiceException(415, Strings.BadRequest_InvalidContentType(host.RequestContentType, description.TargetResourceType.Name));
                    }
                    else
                    {
                        throw new DataServiceException(415, Strings.BadRequest_InvalidContentTypeForOpenProperty(host.RequestContentType, description.ContainerName));
                    }
                }

                if (requestFormat == ContentFormat.Binary)
                {
                    byte[] propertyValue = ReadByteStream(stream);
                    if (description.Property != null && description.Property.Type == typeof(System.Data.Linq.Binary))
                    {
                        requestValue = new System.Data.Linq.Binary(propertyValue);
                    }
                    else
                    {
                        requestValue = propertyValue;
                    }
                }
                else
                {
                    Debug.Assert(requestFormat == ContentFormat.Text, "requestFormat == ContentFormat.Text");
                    Debug.Assert(encoding != null, "encoding != null");
                    StreamReader requestReader = new StreamReader(stream, encoding);
                    string propertyValue = Deserializer.ReadStringFromStream(requestReader);

                    if (description.Property != null && propertyValue != null)
                    {
                        try
                        {
                            // Convert the property value to the correct type
                            requestValue = WebConvert.StringToPrimitive((string)propertyValue, description.Property.Type);
                        }
                        catch (FormatException e)
                        {
                            throw DataServiceException.CreateBadRequestError(Strings.BadRequest_ErrorInConvertingPropertyValue(description.Property.Name, description.Property.Type), e);
                        }
                    }
                    else
                    {
                        // For open types, there is no conversion required. There is not enough information to do the conversion.
                        requestValue = propertyValue;
                    }
                }
            }
            else if (description.TargetKind == RequestTargetKind.MediaResource)
            {
                requestFormat = ContentFormat.Binary;
                requestValue = stream;
            }
            else
            {
                requestFormat = WebUtil.SelectRequestFormat(mimeType, description);
                using (Deserializer deserializer = Deserializer.CreateDeserializer(description, dataService, true /*update*/, tracker))
                {
                    if (description.LinkUri)
                    {
                        string uri = deserializer.GetLinkUriFromPayload();

                        // No need to check for null - if the uri in the payload is /Customer(1)/BestFriend,
                        // and the value is null, it means that the user wants to set the current link to null
                        // i.e. in other words, unbind the relationship.
                        object linkResource = deserializer.GetTargetResourceToBind(uri, true /*checkNull*/);
                        entityGettingModified = Deserializer.HandleBindOperation(description, linkResource, deserializer.Service, deserializer.Tracker);
                        container = description.LastSegmentInfo.TargetContainer;
                    }
                    else
                    {
                        requestValue = deserializer.ReadEntity(description);

                        if (requestValue == null &&
                            description.LastSegmentInfo.HasKeyValues &&
                            description.TargetSource == RequestTargetSource.EntitySet)
                        {
                            throw DataServiceException.CreateBadRequestError(Strings.BadRequest_CannotSetTopLevelResourceToNull(description.ResultUri.OriginalString));
                        }
                    }
                }
            }

            // Update the property value, if the request target is property
            if (!description.LinkUri && IsQueryRequired(description, requestValue, dataService.Provider))
            {
                // Get the parent entity and its container and the resource to modify
                object resourceToModify = GetResourceToModify(
                    description, dataService, false /*allowCrossReferencing*/, out entityGettingModified, out container, true /*checkETag*/);

                tracker.TrackAction(entityGettingModified, container, UpdateOperations.Change);

                Deserializer.ModifyResource(description, resourceToModify, requestValue, requestFormat, dataService);
            }

            tracker.FireNotifications();

            if (entityGettingModified == null)
            {
                entityGettingModified = requestValue;
                container = description.LastSegmentInfo.TargetContainer;
            }

            return RequestDescription.CreateSingleResultRequestDescription(description, entityGettingModified, container);
        }
Exemplo n.º 59
0
 public string Read(string key, out RequestDescription result)
 {
     return(_redisTable.Read(key, out result));
 }
Exemplo n.º 60
0
        /// <summary>
        /// Copy the contents of the request stream into the default stream of the specified entity.
        /// </summary>
        /// <param name="resourceToBeModified">Entity with the associated stream which we will write to.</param>
        /// <param name="requestStream">Request stream from the host</param>
        /// <param name="service">Service this is request is against</param>
        /// <param name="description">Description of the target request.</param>
        internal static void SetStreamPropertyValue(object resourceToBeModified, Stream requestStream, IDataService service, RequestDescription description)
        {
            Debug.Assert(resourceToBeModified != null, "resourceToBeModified != null");
            Debug.Assert(requestStream.CanRead, "requestStream.CanRead");
            Debug.Assert(service != null, "service != null");

            resourceToBeModified = service.Updatable.ResolveResource(resourceToBeModified);
            ResourceType resourceType = service.Provider.GetResourceType(resourceToBeModified);

            // We are here because one of the following conditions is true:
            // 1. This is a POST MR, in which case we get here because resourceType.IsMediaLinkEntry is true.
            // 2. This is a PUT default/named stream, so target kind is MediaResource but resourceType can be either an MLE or non-MLE.
            //
            // If target kind is MediaResource and this is not a named stream, the current endpoint is /entity/$value. We need to verify that
            // resourceType is an MLE. At URI processing time, we don't have the actual entity instance to test whether it is an MLE or not, so
            // we postpone the test untill now.
            if (description.TargetKind == RequestTargetKind.MediaResource && !description.IsNamedStream && !resourceType.IsMediaLinkEntry)
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidUriForMediaResource(service.OperationContext.AbsoluteRequestUri));
            }

            if (service.OperationContext.RequestMessage.HttpVerb == HttpVerbs.PATCH)
            {
                throw DataServiceException.CreateMethodNotAllowed(
                    Strings.BadRequest_InvalidUriForPatchOperation(service.OperationContext.AbsoluteRequestUri),
                    DataServiceConfiguration.GetAllowedMethods(service.Configuration, description));
            }

            Debug.Assert(
                (service.OperationContext.RequestMessage.HttpVerb == HttpVerbs.POST && resourceType.IsMediaLinkEntry) ||
                (service.OperationContext.RequestMessage.HttpVerb == HttpVerbs.PUT && description.TargetKind == RequestTargetKind.MediaResource),
                "We are here because this is either a POST to an Atom MR or a PUT to a default/named stream.");

            ResourceProperty streamProperty = null; // null for default stream.
            if (description.TargetKind == RequestTargetKind.MediaResource)
            {
                streamProperty = description.StreamProperty;
            }

            using (Stream writeStream = service.StreamProvider.GetWriteStream(resourceToBeModified, streamProperty, service.OperationContext))
            {
                WebUtil.CopyStream(requestStream, writeStream, service.StreamProvider.StreamBufferSize);
            }
        }