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

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

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

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

            this.requestStream = operationMessage.GetStream();
        }
Exemplo n.º 2
0
        /// <summary>
        /// Reads the input request payload and returns the WCF DS value representation of it.
        /// </summary>
        /// <param name="segmentInfo">Info about the request to read. For entity reference requests this is null.</param>
        /// <returns>The WCF DS representation of the value read. For entity reference link this is the Uri of the link.</returns>
        protected override object Read(SegmentInfo segmentInfo)
        {
            Debug.Assert(segmentInfo == null, "segmentInfo == null");
            Debug.Assert(this.RequestDescription.LinkUri, "The EntityReferenceLinkDeserializer only supports $ref payloads.");

            ODataEntityReferenceLink entityReferenceLink = this.MessageReader.ReadEntityReferenceLink();

            Debug.Assert(entityReferenceLink != null, "ReadEntityReferenceLink should never return null.");
            Uri entityReferenceUri = entityReferenceLink.Url;

            Debug.Assert(entityReferenceUri != null, "The Url of the entity reference link should never be null.");
#pragma warning disable 618
            AssertReaderFormatIsExpected(this.MessageReader, ODataFormat.Atom, ODataFormat.Json);
#pragma warning restore 618

            // We must fail on empty URI
            string entityReferenceUriAsString = UriUtil.UriToString(entityReferenceUri);
            if (string.IsNullOrEmpty(entityReferenceUriAsString))
            {
                throw DataServiceException.CreateBadRequestError(Microsoft.OData.Service.Strings.BadRequest_MissingUriForLinkOperation);
            }

            // Resolve the URI against the service
            return(RequestUriProcessor.GetAbsoluteUriFromReference(entityReferenceUri, this.Service.OperationContext.AbsoluteServiceUri));
        }
Exemplo n.º 3
0
        private void SetResourceReferenceToUrl(object entityResource, ResourceProperty navigationProperty, string url)
        {
            base.CheckAndIncrementObjectCount();
            RequestDescription description = RequestUriProcessor.ProcessRequestUri(RequestUriProcessor.GetAbsoluteUriFromReference(url, base.Service.OperationContext), base.Service, true);

            if ((this.ContentFormat == ContentFormat.Atom) && !description.IsSingleResult)
            {
                if ((navigationProperty != null) && (navigationProperty.Kind == ResourcePropertyKind.ResourceReference))
                {
                    throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.BadRequest_LinkHrefMustReferToSingleResource(navigationProperty.Name));
                }
            }
            else
            {
                object propertyValue = base.Service.GetResource(description, description.SegmentInfos.Length - 1, null);
                if (navigationProperty.Kind == ResourcePropertyKind.ResourceReference)
                {
                    base.Updatable.SetReference(entityResource, navigationProperty.Name, propertyValue);
                }
                else
                {
                    WebUtil.CheckResourceExists(propertyValue != null, description.LastSegmentInfo.Identifier);
                    base.Updatable.AddReferenceToCollection(entityResource, navigationProperty.Name, propertyValue);
                }
            }
        }
Exemplo n.º 4
0
        protected override object Read(System.Data.Services.SegmentInfo segmentInfo)
        {
            Uri url = base.MessageReader.ReadEntityReferenceLink().Url;

            if (string.IsNullOrEmpty(CommonUtil.UriToString(url)))
            {
                throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.BadRequest_MissingUriForLinkOperation);
            }
            return(RequestUriProcessor.GetAbsoluteUriFromReference(url, base.Service.OperationContext.AbsoluteServiceUri, base.RequestDescription.RequestVersion));
        }
Exemplo n.º 5
0
        /// <summary>
        /// Initializes a new dummy host for the batch request.
        /// This host represents a single operation in the batch.
        /// </summary>
        /// <param name="absoluteServiceUri">absolute Uri to the service</param>
        /// <param name="batchStream">batch stream which contains the header information.</param>
        /// <param name="contentId">content id for the given operation host.</param>
        /// <param name='boundary'>Response separator string.</param>
        /// <param name='writer'>Output writer.</param>
        internal BatchServiceHost(Uri absoluteServiceUri, BatchStream batchStream, string contentId, string boundary, StreamWriter writer)
            : this(boundary, writer)
        {
            Debug.Assert(absoluteServiceUri != null && absoluteServiceUri.IsAbsoluteUri, "absoluteServiceUri != null && absoluteServiceUri.IsAbsoluteUri");
            Debug.Assert(batchStream != null, "batchStream != null");

            this.absoluteServiceUri = absoluteServiceUri;
            this.absoluteRequestUri = RequestUriProcessor.GetAbsoluteUriFromReference(batchStream.ContentUri, absoluteServiceUri);
            this.requestHttpMethod  = GetHttpMethodName(batchStream.State);
            this.requestStream      = batchStream.GetContentStream();
            this.contentId          = contentId;

            foreach (KeyValuePair <string, string> header in batchStream.ContentHeaders)
            {
                this.requestHeaders.Add(header.Key, header.Value);
            }
        }
Exemplo n.º 6
0
 internal BatchServiceHost(Uri absoluteServiceUri, IODataRequestMessage operationMessage, string contentId, ODataBatchWriter writer, Version maxDataServiceVersion, Version minDataServiceVersion, Version dataServiceVersion) : this(writer)
 {
     this.absoluteServiceUri = absoluteServiceUri;
     this.absoluteRequestUri = RequestUriProcessor.GetAbsoluteUriFromReference(operationMessage.Url, absoluteServiceUri, dataServiceVersion);
     this.requestHttpMethod  = operationMessage.Method;
     this.contentId          = contentId;
     foreach (KeyValuePair <string, string> pair in operationMessage.Headers)
     {
         this.requestHeaders.Add(pair.Key, pair.Value);
     }
     if (string.IsNullOrEmpty(this.requestHeaders["MaxDataServiceVersion"]))
     {
         this.requestHeaders["MaxDataServiceVersion"] = maxDataServiceVersion.ToString();
     }
     if (string.IsNullOrEmpty(this.requestHeaders["MinDataServiceVersion"]))
     {
         this.requestHeaders["MinDataServiceVersion"] = minDataServiceVersion.ToString();
     }
     this.requestStream = operationMessage.GetStream();
 }
Exemplo n.º 7
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.º 8
0
        protected object GetTargetResourceToBind(string uri, bool checkNull)
        {
            Uri absoluteUriFromReference = RequestUriProcessor.GetAbsoluteUriFromReference(uri, this.Service.OperationContext);

            return(this.GetTargetResourceToBind(absoluteUriFromReference, checkNull));
        }
Exemplo n.º 9
0
        /// <summary>Applies the information from a link to the specified resource.</summary>
        /// <param name='link'>LinkDescriptor with information to apply.</param>
        /// <param name="resourceSet">Set for the target resource.</param>
        /// <param name='resourceType'>Type for the target resource.</param>
        /// <param name='resource'>Target resource to which information will be applied.</param>
        /// <param name="propertyName">Name of the property that this link represents.</param>
        private void ApplyLink(SyndicationLink link, ResourceSetWrapper resourceSet, ResourceType resourceType, object resource, string propertyName)
        {
            Debug.Assert(link != null, "link != null");
            Debug.Assert(resourceType != null, "resourceType != null");
            Debug.Assert(resource != null, "resource != null");

            ResourceProperty property = resourceType.TryResolvePropertyName(propertyName);

            if (property == null)
            {
                // Open navigation properties are not supported on OpenTypes
                throw DataServiceException.CreateBadRequestError(Strings.OpenNavigationPropertiesNotSupportedOnOpenTypes(propertyName));
            }

            if (property.TypeKind != ResourceTypeKind.EntityType)
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidNavigationPropertyName(propertyName, resourceType.FullName));
            }

            string      typeParameterValue = ValidateTypeParameterForNonOpenTypeProperties(link.MediaType, property);
            LinkContent linkContent        = this.HandleLinkContent(link, resource, resourceSet, resourceType, property, typeParameterValue, propertyName);

            #region Handle bind/unbind operation
            // If the href was specified empty or an empty inline element was specified, then we will set the
            // reference to null - this helps in overrriding if there was a default non-value for this property
            // else if only link element was specified, and then href points to a single result, then we will
            // perform a bind operation
            if ((linkContent == LinkContent.NoInlineElementSpecified && link.Uri != null && String.IsNullOrEmpty(link.Uri.OriginalString)) ||
                linkContent == LinkContent.EmptyInlineElementSpecified)
            {
                // update the object count when you are performing a bind operation
                this.CheckAndIncrementObjectCount();
                if (property != null && property.Kind == ResourcePropertyKind.ResourceSetReference)
                {
                    throw DataServiceException.CreateBadRequestError(Strings.BadRequest_CannotSetCollectionsToNull(propertyName));
                }

                // For open properties, we will assume that this is a reference property and set it to null
                this.Updatable.SetReference(resource, propertyName, null);
            }
            else if (linkContent == LinkContent.NoInlineElementSpecified && link.Uri != null && !String.IsNullOrEmpty(link.Uri.OriginalString))
            {
                // update the object count when you are performing a bind operation
                this.CheckAndIncrementObjectCount();

                // If the link points to a reference navigation property, then update the link
                Uri referencedUri = RequestUriProcessor.GetAbsoluteUriFromReference(link.Uri.OriginalString, this.Service.OperationContext);
                RequestDescription description = RequestUriProcessor.ProcessRequestUri(referencedUri, this.Service);
                if (!description.IsSingleResult)
                {
                    if (property != null && property.Kind == ResourcePropertyKind.ResourceReference)
                    {
                        throw DataServiceException.CreateBadRequestError(Strings.BadRequest_LinkHrefMustReferToSingleResource(propertyName));
                    }

                    return;
                }

                // no need to check for null. For collection properties, they can never be null and that
                // check has been added below. For reference properties, if they are null, it means unbind
                // and hence no need to check for null.
                // Get the resource
                object targetResource = this.Service.GetResource(description, description.SegmentInfos.Length - 1, null);
                if (property.Kind == ResourcePropertyKind.ResourceReference)
                {
                    this.Updatable.SetReference(resource, propertyName, targetResource);
                }
                else
                {
                    WebUtil.CheckResourceExists(targetResource != null, description.LastSegmentInfo.Identifier);
                    this.Updatable.AddReferenceToCollection(resource, propertyName, targetResource);
                }
            }
            #endregion Handle bind/unbind operation
        }