edfbe55796cf502414a339338694a8dc240dad20.svn-base 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Data.Objects;
  5. using System.Data.Services;
  6. using System.Data.Services.Providers;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Security.Cryptography;
  10. using System.Text;
  11. using System.Web;
  12. using System.Web.Hosting;
  13. using DevExpress.XtraPrinting.Native;
  14. using iBemsDataService.Model;
  15. using iBemsDataService.Util;
  16. namespace iBemsDataService
  17. {
  18. public interface IImageSource
  19. {
  20. byte[] Image { get; }
  21. }
  22. /*
  23. * 두번째 <EntityType Name="CmFile"> 에
  24. * m:HasStream="true" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
  25. * 를 수동으로 추가하여야 한다.
  26. * <EntityType Name="CmFile" m:HasStream="true" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
  27. * */
  28. public class ImageStreamProvider : IDataServiceStreamProvider, IDisposable
  29. {
  30. private string _tempFile;
  31. private string _filePath;
  32. private CmFile _cachedEntity;
  33. private iBemsEntities _context;
  34. private static Dictionary<string , string> _fileCategories = new Dictionary<string , string>();
  35. public ImageStreamProvider( iBemsEntities context )
  36. {
  37. _context = context;
  38. // Get the physical path to the app_data directory used to store the image files.
  39. _filePath = HostingEnvironment.MapPath( "~/App_Data/" );
  40. // Create a temp file to store the new images during POST operations.
  41. _tempFile = Path.GetTempFileName();
  42. }
  43. public void DeleteStream( object entity , DataServiceOperationContext operationContext )
  44. {
  45. var file = entity as CmFile;
  46. if( file == null )
  47. {
  48. throw new DataServiceException( 500 , "Internal Server Error." );
  49. }
  50. try
  51. {
  52. // Delete the requested file by using the key value.
  53. File.Delete( FileCategoryManager.GetInstance().GetFilePath( file ) );
  54. }
  55. catch( IOException ex )
  56. {
  57. throw new DataServiceException( "The file could not be found." , ex );
  58. }
  59. }
  60. public Stream GetReadStream( object entity , string etag , bool? checkETagForEquality , DataServiceOperationContext operationContext )
  61. {
  62. if( checkETagForEquality != null )
  63. {
  64. throw new DataServiceException( 400 , "This service does not support the ETag header for a media resource." );
  65. }
  66. var file = entity as CmFile;
  67. if( file == null )
  68. {
  69. throw new DataServiceException( 500 , "Internal Server Error." );
  70. }
  71. // Build the full path to the stored image file, which includes the entity key.
  72. string filePath = FileCategoryManager.GetInstance().GetFilePath( file );
  73. if( !File.Exists( filePath ) )
  74. {
  75. throw new DataServiceException( 500 , "The file could not be found." );
  76. }
  77. if ( IsImageType( file ) == false )
  78. {
  79. //operationContext.ResponseHeaders["Content-Disposition"] = "attachment; filename=\"" + file.Name + "\"";
  80. //operationContext.ResponseHeaders["Content-Disposition"] = "attachment; filename=" + "//" + file.Name + "//";
  81. //operationContext.ResponseHeaders["Content-Disposition"] = "attachment; filename=" + file.Name;
  82. /*
  83. string contentDisposition;
  84. if (Request.Browser.Browser == "IE" && (Request.Browser.Version == "7.0" || Request.Browser.Version == "8.0"))
  85. contentDisposition = "attachment; filename=" + Uri.EscapeDataString(fileName);
  86. else if (Request.UserAgent != null && Request.UserAgent.ToLowerInvariant().Contains("android")) // android built-in download manager (all browsers on android)
  87. contentDisposition = "attachment; filename=\"" + MakeAndroidSafeFileName(fileName) + "\"";
  88. else
  89. contentDisposition = "attachment; filename=\"" + fileName + "\"; filename*=UTF-8''" + Uri.EscapeDataString(fileName);
  90. Response.AddHeader("Content-Disposition", contentDisposition); */
  91. string strDispos = "attachment; filename= " + Uri.EscapeDataString(file.Name);
  92. //string strDispos = "attachment; filename=\"" + file.Name + "\"; filename*=UTF-8''" + Uri.EscapeDataString(file.Name);
  93. operationContext.ResponseHeaders["Content-Disposition"] = strDispos;
  94. }
  95. // Return a stream that contains the requested file.
  96. return new FileStream( filePath, FileMode.Open );
  97. }
  98. protected bool IsImageType( CmFile file )
  99. {
  100. var types = file.ContentType.Split( '/' );
  101. return ( types.Length > 0 && types[0].ToLower() == "image" );
  102. }
  103. public Uri GetReadStreamUri( object entity , DataServiceOperationContext operationContext )
  104. {
  105. return null;
  106. }
  107. public string GetStreamContentType( object entity , DataServiceOperationContext operationContext )
  108. {
  109. var file = entity as CmFile;
  110. if( file == null )
  111. {
  112. throw new DataServiceException( 500 , "Internal Server Error." );
  113. }
  114. return file.ContentType;
  115. }
  116. public string GetStreamETag( object entity , DataServiceOperationContext operationContext )
  117. {
  118. return null;
  119. }
  120. public Stream GetWriteStream( object entity , string etag , bool? checkETagForEquality , DataServiceOperationContext operationContext )
  121. {
  122. if( checkETagForEquality != null )
  123. {
  124. throw new DataServiceException( 400 , "This service does not support ETags associated with BLOBs" );
  125. }
  126. var file = entity as CmFile;
  127. if( file == null )
  128. {
  129. throw new DataServiceException( 500 , "Internal Server Error: " + "the Media Link Entry could not be determined." );
  130. }
  131. // Handle the POST request.
  132. if( operationContext.RequestMethod == "POST" )
  133. {
  134. // Set the file name from the Slug header; if we don't have a
  135. // Slug header, just set a temporary name which is overwritten
  136. // by the subsequent MERGE request from the client.
  137. file.Name = operationContext.RequestHeaders["Slug"] ?? "newFile";
  138. // Set the required DateTime values.
  139. file.CreatedDate = DateTime.Today;
  140. // Set the content type, which cannot be null.
  141. file.ContentType = operationContext.RequestHeaders["Content-Type"];
  142. // Cache the current entity to enable us to both create a key based storage file name
  143. // and to maintain transactional integrity in the disposer; we do this only for a POST request.
  144. _cachedEntity = file;
  145. return new FileStream( _tempFile , FileMode.Open );
  146. }
  147. // Handle the PUT request
  148. else
  149. {
  150. // Return a stream to write to an existing file.
  151. return new FileStream( FileCategoryManager.GetInstance().GetFilePath( file ) , FileMode.Open , FileAccess.Write );
  152. }
  153. }
  154. public string GetFileCategoryPath( string fileCategoryName )
  155. {
  156. var sb = new StringBuilder();
  157. sb.Append( _filePath );
  158. sb.Append( "files/" );
  159. sb.Append( fileCategoryName );
  160. return sb.ToString();
  161. }
  162. public string ResolveType( string entitySetName , DataServiceOperationContext operationContext )
  163. {
  164. if ( entitySetName == "CmFile" )
  165. {
  166. return "BemsDataService." + entitySetName;
  167. }
  168. return null;
  169. }
  170. public int StreamBufferSize
  171. {
  172. get { return 64000; }
  173. }
  174. public void Dispose()
  175. {
  176. // If we have a cached entity, it must be a POST request.
  177. if( _cachedEntity != null )
  178. {
  179. // Get the new entity from the Entity Framework object state manager.
  180. var state = _context.Entry( _cachedEntity ).State;
  181. if( state == EntityState.Unchanged )
  182. {
  183. // Since the entity was created successfully, move the temp file into the
  184. // storage directory and rename the file based on the new entity key.
  185. File.Move( _tempFile , FileCategoryManager.GetInstance().GetFilePath( _cachedEntity ) );
  186. // Delete the temp file.
  187. File.Delete( _tempFile );
  188. }
  189. else
  190. {
  191. // A problem must have occurred when saving the entity to the database,
  192. // so we should delete the entity and temp file.
  193. _context.CmFile.Remove( _cachedEntity );
  194. _context.SaveChanges();
  195. File.Delete( _tempFile );
  196. throw new DataServiceException( "An error occurred. The file could not be saved." );
  197. }
  198. }
  199. }
  200. }
  201. }