/// <summary> /// Initializes a new dummy host for the batch request. /// This host represents a single operation in the batch. /// </summary> /// <param name="absoluteServiceUri">Absolute Uri to the service.</param> /// <param name="operationMessage">The request message representing a batch operation to wrap.</param> /// <param name="contentId">Content id for the given operation host.</param> /// <param name="writer">ODataBatchWriter instance.</param> /// <param name="odataMaxVersion">OData-MaxVersion header on the batch request. If the OData-MaxVersion header is not specified in the current operation, we default to the MaxDSV from the batch level.</param> internal BatchServiceHost(Uri absoluteServiceUri, IODataRequestMessage operationMessage, string contentId, ODataBatchWriter writer, Version odataMaxVersion) : this(writer) { Debug.Assert(absoluteServiceUri != null && absoluteServiceUri.IsAbsoluteUri, "absoluteServiceUri != null && absoluteServiceUri.IsAbsoluteUri"); Debug.Assert(operationMessage != null, "operationMessage != null"); this.absoluteServiceUri = absoluteServiceUri; this.absoluteRequestUri = RequestUriProcessor.GetAbsoluteUriFromReference(operationMessage.Url, absoluteServiceUri); this.requestHttpMethod = operationMessage.Method; this.contentId = contentId; foreach (KeyValuePair <string, string> header in operationMessage.Headers) { this.requestHeaders.Add(header.Key, header.Value); } // If the MaxDSV header is not specified in the current operation, we default to the MaxDSV from the batch level. if (string.IsNullOrEmpty(this.requestHeaders[XmlConstants.HttpODataMaxVersion])) { Debug.Assert(odataMaxVersion != null, "odataMaxVersion != null"); this.requestHeaders[XmlConstants.HttpODataMaxVersion] = odataMaxVersion.ToString(); } this.requestStream = operationMessage.GetStream(); }
/// <summary> /// 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)); }
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); } } }
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)); }
/// <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); } }
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(); }
/// <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); } }
protected object GetTargetResourceToBind(string uri, bool checkNull) { Uri absoluteUriFromReference = RequestUriProcessor.GetAbsoluteUriFromReference(uri, this.Service.OperationContext); return(this.GetTargetResourceToBind(absoluteUriFromReference, checkNull)); }
/// <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 }