123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Data.Objects;
- using System.Data.Services;
- using System.Data.Services.Providers;
- using System.IO;
- using System.Linq;
- using System.Security.Cryptography;
- using System.Text;
- using System.Web;
- using System.Web.Hosting;
- using DevExpress.XtraPrinting.Native;
- using iBemsDataService.Model;
- using iBemsDataService.Util;
- namespace iBemsDataService
- {
- public interface IImageSource
- {
- byte[] Image { get; }
- }
- /*
- * 두번째 <EntityType Name="CmFile"> 에
- * m:HasStream="true" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
- * 를 수동으로 추가하여야 한다.
- * <EntityType Name="CmFile" m:HasStream="true" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
- * */
- public class ImageStreamProvider : IDataServiceStreamProvider, IDisposable
- {
- private string _tempFile;
- private string _filePath;
- private CmFile _cachedEntity;
- private iBemsEntities _context;
- private static Dictionary<string , string> _fileCategories = new Dictionary<string , string>();
- public ImageStreamProvider( iBemsEntities context )
- {
- _context = context;
- // Get the physical path to the app_data directory used to store the image files.
- _filePath = HostingEnvironment.MapPath( "~/App_Data/" );
- // Create a temp file to store the new images during POST operations.
- _tempFile = Path.GetTempFileName();
- }
- public void DeleteStream( object entity , DataServiceOperationContext operationContext )
- {
- var file = entity as CmFile;
- if( file == null )
- {
- throw new DataServiceException( 500 , "Internal Server Error." );
- }
- try
- {
- // Delete the requested file by using the key value.
- File.Delete( FileCategoryManager.GetInstance().GetFilePath( file ) );
- }
- catch( IOException ex )
- {
- throw new DataServiceException( "The file could not be found." , ex );
- }
- }
- public Stream GetReadStream( object entity , string etag , bool? checkETagForEquality , DataServiceOperationContext operationContext )
- {
- if( checkETagForEquality != null )
- {
- throw new DataServiceException( 400 , "This service does not support the ETag header for a media resource." );
- }
-
- var file = entity as CmFile;
- if( file == null )
- {
- throw new DataServiceException( 500 , "Internal Server Error." );
- }
- // Build the full path to the stored image file, which includes the entity key.
- string filePath = FileCategoryManager.GetInstance().GetFilePath( file );
- if( !File.Exists( filePath ) )
- {
- throw new DataServiceException( 500 , "The file could not be found." );
- }
- if ( IsImageType( file ) == false )
- {
- //operationContext.ResponseHeaders["Content-Disposition"] = "attachment; filename=\"" + file.Name + "\"";
- //operationContext.ResponseHeaders["Content-Disposition"] = "attachment; filename=" + "//" + file.Name + "//";
- //operationContext.ResponseHeaders["Content-Disposition"] = "attachment; filename=" + file.Name;
- /*
- string contentDisposition;
- if (Request.Browser.Browser == "IE" && (Request.Browser.Version == "7.0" || Request.Browser.Version == "8.0"))
- contentDisposition = "attachment; filename=" + Uri.EscapeDataString(fileName);
- else if (Request.UserAgent != null && Request.UserAgent.ToLowerInvariant().Contains("android")) // android built-in download manager (all browsers on android)
- contentDisposition = "attachment; filename=\"" + MakeAndroidSafeFileName(fileName) + "\"";
- else
- contentDisposition = "attachment; filename=\"" + fileName + "\"; filename*=UTF-8''" + Uri.EscapeDataString(fileName);
- Response.AddHeader("Content-Disposition", contentDisposition); */
- string strDispos = "attachment; filename= " + Uri.EscapeDataString(file.Name);
- //string strDispos = "attachment; filename=\"" + file.Name + "\"; filename*=UTF-8''" + Uri.EscapeDataString(file.Name);
- operationContext.ResponseHeaders["Content-Disposition"] = strDispos;
- }
- // Return a stream that contains the requested file.
- return new FileStream( filePath, FileMode.Open );
- }
- protected bool IsImageType( CmFile file )
- {
- var types = file.ContentType.Split( '/' );
- return ( types.Length > 0 && types[0].ToLower() == "image" );
- }
- public Uri GetReadStreamUri( object entity , DataServiceOperationContext operationContext )
- {
- return null;
- }
- public string GetStreamContentType( object entity , DataServiceOperationContext operationContext )
- {
- var file = entity as CmFile;
- if( file == null )
- {
- throw new DataServiceException( 500 , "Internal Server Error." );
- }
- return file.ContentType;
- }
- public string GetStreamETag( object entity , DataServiceOperationContext operationContext )
- {
- return null;
- }
- public Stream GetWriteStream( object entity , string etag , bool? checkETagForEquality , DataServiceOperationContext operationContext )
- {
- if( checkETagForEquality != null )
- {
- throw new DataServiceException( 400 , "This service does not support ETags associated with BLOBs" );
- }
- var file = entity as CmFile;
- if( file == null )
- {
- throw new DataServiceException( 500 , "Internal Server Error: " + "the Media Link Entry could not be determined." );
- }
- // Handle the POST request.
- if( operationContext.RequestMethod == "POST" )
- {
- // Set the file name from the Slug header; if we don't have a
- // Slug header, just set a temporary name which is overwritten
- // by the subsequent MERGE request from the client.
- file.Name = operationContext.RequestHeaders["Slug"] ?? "newFile";
- // Set the required DateTime values.
- file.CreatedDate = DateTime.Today;
- // Set the content type, which cannot be null.
- file.ContentType = operationContext.RequestHeaders["Content-Type"];
- // Cache the current entity to enable us to both create a key based storage file name
- // and to maintain transactional integrity in the disposer; we do this only for a POST request.
- _cachedEntity = file;
- return new FileStream( _tempFile , FileMode.Open );
- }
- // Handle the PUT request
- else
- {
- // Return a stream to write to an existing file.
- return new FileStream( FileCategoryManager.GetInstance().GetFilePath( file ) , FileMode.Open , FileAccess.Write );
- }
- }
- public string GetFileCategoryPath( string fileCategoryName )
- {
- var sb = new StringBuilder();
- sb.Append( _filePath );
- sb.Append( "files/" );
- sb.Append( fileCategoryName );
- return sb.ToString();
- }
- public string ResolveType( string entitySetName , DataServiceOperationContext operationContext )
- {
- if ( entitySetName == "CmFile" )
- {
- return "BemsDataService." + entitySetName;
- }
- return null;
- }
- public int StreamBufferSize
- {
- get { return 64000; }
- }
- public void Dispose()
- {
- // If we have a cached entity, it must be a POST request.
- if( _cachedEntity != null )
- {
- // Get the new entity from the Entity Framework object state manager.
- var state = _context.Entry( _cachedEntity ).State;
- if( state == EntityState.Unchanged )
- {
- // Since the entity was created successfully, move the temp file into the
- // storage directory and rename the file based on the new entity key.
- File.Move( _tempFile , FileCategoryManager.GetInstance().GetFilePath( _cachedEntity ) );
- // Delete the temp file.
- File.Delete( _tempFile );
- }
- else
- {
- // A problem must have occurred when saving the entity to the database,
- // so we should delete the entity and temp file.
- _context.CmFile.Remove( _cachedEntity );
- _context.SaveChanges();
- File.Delete( _tempFile );
- throw new DataServiceException( "An error occurred. The file could not be saved." );
- }
- }
- }
- }
- }
|