internal MetadataProviderEdmModel(DataServiceProviderWrapper provider, DataServiceOperationContext operationContext, DataServiceStreamProviderWrapper streamProviderWrapper) { this.metadataProvider = provider; this.operationContext = operationContext; this.streamProviderWrapper = streamProviderWrapper; this.schemaTypeCache = new Dictionary <string, IEdmSchemaType>(StringComparer.Ordinal); this.resourceTypesPerNamespaceCache = new Dictionary <string, HashSet <ResourceType> >(StringComparer.Ordinal); this.entityContainerCache = new Dictionary <string, MetadataProviderEdmEntityContainer>(StringComparer.Ordinal); this.primitiveOrComplexCollectionTypeCache = new Dictionary <ResourceType, IEdmCollectionType>(EqualityComparer <ResourceType> .Default); this.entityPrimitiveOrComplexCollectionTypeCache = new Dictionary <ResourceType, IEdmCollectionType>(EqualityComparer <ResourceType> .Default); this.derivedTypeMappings = new Dictionary <IEdmStructuredType, List <IEdmStructuredType> >(EqualityComparer <IEdmStructuredType> .Default); this.associationSetByKeyCache = new Dictionary <string, string>(StringComparer.Ordinal); Version version = this.metadataProvider.Configuration.DataServiceBehavior.MaxProtocolVersion.ToVersion(); this.SetDataServiceVersion(version); Version version2 = null; if (!MetadataProviderUtils.DataServiceEdmVersionMap.TryGetValue(version, out version2)) { this.SetEdmVersion(Microsoft.Data.Edm.Library.EdmConstants.EdmVersionLatest); } else { this.SetEdmVersion(version2); } }
/// <summary> /// This method is invoked by the data services framework to retrieve the default stream associated /// with the Entity Type specified by the <paramref name="entity"/> parameter. /// Note that we set the response ETag in the host object before we return. /// </summary> /// <param name="entity">The stream returned should be the default stream associated with this entity.</param> /// <param name="operationContext">A reference to the context for the current operation.</param> /// <returns>A valid stream the data service use to query / read a streamed BLOB which is associated with the <paramref name="entity"/>.</returns> internal Stream GetReadStream(object entity, DataServiceOperationContext operationContext) { Debug.Assert(entity != null, "entity != null"); Debug.Assert(operationContext != null, "operationContext != null"); string etagFromHeader; bool? checkETagForEquality; DataServiceStreamProviderWrapper.GetETagFromHeaders(operationContext, out etagFromHeader, out checkETagForEquality); Debug.Assert( string.IsNullOrEmpty(etagFromHeader) && !checkETagForEquality.HasValue || !string.IsNullOrEmpty(etagFromHeader) && checkETagForEquality.HasValue, "etag and checkETagForEquality parameters must both be set or not set at the same time."); Stream readStream = null; try { readStream = InvokeApiCallAndValidateHeaders("IDataServiceStreamProvider.GetReadStream", () => this.StreamProvider.GetReadStream(entity, etagFromHeader, checkETagForEquality, operationContext), operationContext); } catch (DataServiceException e) { if (e.StatusCode == (int)System.Net.HttpStatusCode.NotModified) { // For status code 304, we MUST set the etag value. Our Error handler will translate // DataServiceException(304) to a normal response with status code 304 and an empty message-body. #if DEBUG WebUtil.WriteETagValueInResponseHeader(null, this.GetStreamETag(entity, operationContext), operationContext.Host); #else WebUtil.WriteETagValueInResponseHeader(this.GetStreamETag(entity, operationContext), operationContext.Host); #endif } throw; } try { if (readStream == null || !readStream.CanRead) { throw new InvalidOperationException(Strings.DataService_InvalidStreamFromGetReadStream); } // GetStreamETag can throw and we need to catch and dispose the stream. #if DEBUG WebUtil.WriteETagValueInResponseHeader(null, this.GetStreamETag(entity, operationContext), operationContext.Host); #else WebUtil.WriteETagValueInResponseHeader(this.GetStreamETag(entity, operationContext), operationContext.Host); #endif } catch { WebUtil.Dispose(readStream); throw; } return(readStream); }
/// <summary> /// This method is invoked by the data services framework to obtain the URI clients should use when making retrieve (ie. GET) /// requests to the stream(ie. Media Resource). This metadata is needed when constructing the payload for the Media Link Entry /// associated with the stream (aka Media Resource). /// /// If IDataServiceStreamProvider.GetReadStreamUri returns a valid Uri, we return that as the Uri to the Media Resource. /// Otherwise we take the given Media Link Entry uri, and construct the default Media Resource Uri. /// </summary> /// <param name="entity">The entity associated with the stream for which a “read stream” is to be obtained</param> /// <param name="operationContext">A reference to the context for the current operation.</param> /// <param name="mediaLinkEntryUri">Uri to the Media Link Entry.</param> /// <returns>The URI clients should use when making retrieve (ie. GET) requests to the stream(ie. Media Resource).</returns> internal Uri GetReadStreamUri(object entity, DataServiceOperationContext operationContext, string mediaLinkEntryUri) { Debug.Assert(entity != null, "entity != null"); Debug.Assert(operationContext != null, "operationContext != null"); Uri readStreamUri = InvokeApiCallAndValidateHeaders("IDataServiceStreamProvider.GetReadStreamUri", () => this.StreamProvider.GetReadStreamUri(entity, operationContext), operationContext); if (readStreamUri != null) { if (!readStreamUri.IsAbsoluteUri) { throw new InvalidOperationException(Strings.DataServiceStreamProviderWrapper_GetReadStreamUriMustReturnAbsoluteUriOrNull); } else { return(readStreamUri); } } else { return(new Uri(DataServiceStreamProviderWrapper.GetStreamEditMediaUri(mediaLinkEntryUri), UriKind.RelativeOrAbsolute)); } }
/// <summary> /// This method is invoked by the data services framework whenever an insert or update operation is /// being processed for the stream associated with the Entity Type specified via the entity parameter. /// </summary> /// <param name="entity">The stream returned should be the default stream associated with this entity.</param> /// <param name="operationContext">A reference to the context for the current operation.</param> /// <returns>A valid stream the data service use to write the contents of a BLOB which is associated with <paramref name="entity"/>.</returns> internal Stream GetWriteStream(object entity, DataServiceOperationContext operationContext) { Debug.Assert(entity != null, "entity != null"); Debug.Assert(operationContext != null, "operationContext != null"); string etag; bool? checkETagForEquality; DataServiceStreamProviderWrapper.GetETagFromHeaders(operationContext, out etag, out checkETagForEquality); Debug.Assert( string.IsNullOrEmpty(etag) && !checkETagForEquality.HasValue || !string.IsNullOrEmpty(etag) && checkETagForEquality.HasValue, "etag and checkETagForEquality parameters must both be set or not set at the same time."); Stream writeStream = InvokeApiCallAndValidateHeaders("IDataServiceStreamProvider.GetWriteStream", () => this.StreamProvider.GetWriteStream(entity, etag, checkETagForEquality, operationContext), operationContext); if (writeStream == null || !writeStream.CanWrite) { WebUtil.Dispose(writeStream); throw new InvalidOperationException(Strings.DataService_InvalidStreamFromGetWriteStream); } return(writeStream); }