string IDataServiceStreamProvider.GetStreamETag(object entity, DataServiceOperationContext host) { if (entity is ExternalPicture) { ExternalPicture pict = entity as ExternalPicture; return(pict.BlobETag); } if (entity is InternalPicture) { InternalPicture pict = entity as InternalPicture; // ETag value is timestamp of the storage file if (this.GetEntityState(pict) != EntityState.Added) { this.LoadFileStorageIfItsNotLoaded(pict, "PT.FK_FileStorage_InternalPictures1", "FileStorage"); if (pict.FileStorage == null) { return(null); } var creationTime = System.Data.Test.Astoria.FullTrust.TrustedMethods.GetFileCreationTime(DataPath(pict.FileStorage.Location)); return(string.Concat("\"", creationTime.ToString("dd MMMM yyyy hh:mm:ss.ffffff", System.Globalization.DateTimeFormatInfo.InvariantInfo), "\"")); } } return(null); }
private void ThrowExceptionIfNotPocoWithProxy(InternalPicture source, Exception exception) { if (typeof(InternalPicture) == source.GetType()) { throw exception; } }
Stream IDataServiceStreamProvider.GetReadStream(object entity, string Etag, bool?checkETagForEquality, DataServiceOperationContext host) { //Debug.Assert(entity is InternalPicture || entity is ExternalPicture, "Unexpected entity type!"); if (entity is InternalPicture) { InternalPicture pict = entity as InternalPicture; this.LoadFileStorageIfItsNotLoaded(pict, "PT.FK_FileStorage_InternalPictures1", "FileStorage"); if (pict.FileStorage.ContentDisposition != null) { host.ResponseHeaders.Add("Content-Disposition", pict.FileStorage.ContentDisposition); } if (host.RequestHeaders.AllKeys.Contains("B4C-Sleep")) { string[] slData = host.RequestHeaders["B4C-Sleep"].Split(',', ';', ' '); int lockId = Int32.Parse(slData[0]); int buffSize = Int32.Parse(slData[1]); return(new BlockedFileStream(DataPath(pict.FileStorage.Location), FileMode.Open, FileAccess.Read, FileShare.Read, buffSize, lockId)); } return(new System.Data.Test.Astoria.FullTrust.TrustedFileStream(DataPath(pict.FileStorage.Location), FileMode.Open, FileAccess.Read, FileShare.Read)); } else if (entity is ExternalPicture) { return(new MemoryStream(Encoding.UTF8.GetBytes("This is a replacement for external entity link."), false)); } else { throw new NotSupportedException("Unexpected entity type!"); } }
void IDataServiceStreamProvider.DeleteStream(object entity, DataServiceOperationContext host) { //Debug.Assert(entity is InternalPicture || entity is ExternalPicture, "Unexpected entity type!"); if (entity is InternalPicture) { InternalPicture pict = entity as InternalPicture; FileStorage fs = pict.FileStorage ?? entityContext.FileStorage.FirstOrDefault(f => f.Picture.Id == pict.Id); if (fs != null) { System.Data.Test.Astoria.FullTrust.TrustedMethods.DeleteFileIfExists(DataPath(fs.Location)); entityContext.DeleteObject(fs); } } }
string IDataServiceStreamProvider.GetStreamContentType(object entity, DataServiceOperationContext host) { if (entity is InternalPicture) { InternalPicture pict = entity as InternalPicture; this.LoadFileStorageIfItsNotLoaded(pict, "PT.FK_FileStorage_InternalPictures1", "FileStorage"); return(pict.FileStorage.ContentType); } else if (entity is ExternalPicture) { ExternalPicture pict = entity as ExternalPicture; return(string.IsNullOrEmpty(pict.ContentType) ? "text/plain" : pict.ContentType); } else { throw new NotSupportedException("Unexpected entity type!"); } }
private void LoadFileStorageIfItsNotLoaded(InternalPicture source, string relationshipName, string targetRoleName) { if (source is System.Data.Objects.DataClasses.IEntityWithRelationships) { System.Data.Objects.DataClasses.RelationshipManager relationshipManager = ((System.Data.Objects.DataClasses.IEntityWithRelationships)source).RelationshipManager; var relatedReference = relationshipManager.GetRelatedReference <FileStorage>(relationshipName, targetRoleName); if (!relatedReference.IsLoaded) { try { relatedReference.Load(); } catch (System.Data.EntityException ex) { // expects a first chance exception for PocoWithProxy this.ThrowExceptionIfNotPocoWithProxy(source, ex); } catch (System.InvalidOperationException ex) { // expects a different exception for PocoWithProxy if NoTracking this.ThrowExceptionIfNotPocoWithProxy(source, ex); } } } else { // find FileStorage for PocoWithoutProxy foreach (FileStorage fs in this.entityContext.FileStorage) { if (fs.Id == source.Id) { source.FileStorage = fs; return; } } } }
Stream IDataServiceStreamProvider.GetWriteStream(object entity, string Etag, bool?checkETagForEquality, DataServiceOperationContext host) { //Debug.Assert(entity is InternalPicture, "Unexpected entity type!"); InternalPicture pict = entity as InternalPicture; if (pict != null) { string filename = host.RequestHeaders.AllKeys.Contains("Slug") ? host.RequestHeaders["Slug"] : string.Format("{0}.txt", Guid.NewGuid()); if (filename.Contains(@"FAIL")) { throw new InvalidOperationException("'FAIL' in Slug :: Test hook for exception!"); } string contentType = host.RequestHeaders.AllKeys.Contains("Content-Type") ? host.RequestHeaders["Content-Type"] : null; if (this.GetEntityState(pict) != EntityState.Added) { this.LoadFileStorageIfItsNotLoaded(pict, "PT.FK_FileStorage_InternalPictures1", "FileStorage"); if (pict.FileStorage != null) { if (checkETagForEquality != null) { // the value of checkETagForEquality should be "True" (if-match header). This code does not understand "False" value (if-none-match header). if (!(bool)checkETagForEquality) { throw new NotSupportedException("The service does not support if-none-match header !"); } // if etag does not match, return 412 -> Precondition failed // ETag value is timestamp of the storage file var creationTime = System.Data.Test.Astoria.FullTrust.TrustedMethods.GetFileCreationTime(DataPath(pict.FileStorage.Location)); string fileCreationTimeStamp = string.Concat("\"", creationTime.ToString("dd MMMM yyyy hh:mm:ss.ffffff", System.Globalization.DateTimeFormatInfo.InvariantInfo), "\""); if (fileCreationTimeStamp != Etag) { throw new DataServiceException(412, string.Format("Etag values does not match, expected: {0}, actual: {1}", Etag, fileCreationTimeStamp)); } } pict.FileStorage.ContentType = contentType; pict.FileStorage.Location = filename; } else { // else - trouble, incosistent data - 500(internal error) throw new DataServiceException("Inconsistent data found, giving up!"); } } else { FileStorage fs = new FileStorage { ContentType = contentType, Location = filename, Picture = pict }; entityContext.AddObject("FileStorage", fs); } return(new System.Data.Test.Astoria.FullTrust.TrustedFileStream(DataPath(filename), FileMode.Create, FileAccess.Write, FileShare.Write)); } else { throw new NotSupportedException("Unexpected entity type!"); } }
private void LoadFileStorageIfItsNotLoaded(InternalPicture source, string relationshipName, string targetRoleName) { if (source is System.Data.Objects.DataClasses.IEntityWithRelationships) { System.Data.Objects.DataClasses.RelationshipManager relationshipManager = ((System.Data.Objects.DataClasses.IEntityWithRelationships)source).RelationshipManager; var relatedReference = relationshipManager.GetRelatedReference<FileStorage>(relationshipName, targetRoleName); if (!relatedReference.IsLoaded) { try { relatedReference.Load(); } catch (System.Data.EntityException ex) { // expects a first chance exception for PocoWithProxy this.ThrowExceptionIfNotPocoWithProxy(source, ex); } catch (System.InvalidOperationException ex) { // expects a different exception for PocoWithProxy if NoTracking this.ThrowExceptionIfNotPocoWithProxy(source, ex); } } } else { // find FileStorage for PocoWithoutProxy foreach (FileStorage fs in this.entityContext.FileStorage) { if (fs.Id == source.Id) { source.FileStorage = fs; return; } } } }