ダウンロードファイル(CSアーキテクチャ)について

6388 ワード

以前に作成したWPFプロジェクトでは、サービス側からローカルの指定ディレクトリに画像をダウンロードする必要がある場合に遭遇しました.クライアントページは、この画像が存在するディレクトリのパスをバインドし、この画像をロードするために使用され、画像パスはローカルのデータベースに保存されます.
これらの製品に関する文字情報画像経路情報はいずれもローカルで定期的に更新する必要があり、一般的にクライアントにログインするとバックグラウンドでスレッドを開いて本地表データが最新であるかどうかを取得し、更新があればサービス側から最新のデータをダウンロードする必要がある.では、画像や他のファイルも同じ場合、指定したディレクトリに更新または追加する必要があります.
ここでは、これらのピクチャまたはファイルをサーバの指定した共有ディレクトリに保存し、apiでピクチャを取得してローカルディレクトリに保存します.
サービス側API:
1 ContentTypeConditionクラスを定義し、ダウンロードファイルのパラメータメッセージを渡す.PackageFileNameは画像のパスであり、データベースから取得され、後でフロントエンドダウンロードの論理に言及する.
public class ContentTypeCondition
    {
        public string ID
        {
            get;
            set;
        }

         public string ContentType
        {
            get;
            set;
        }

        public string ConfigFileName
        {
            get;
            set;
        }

        public string PackageFileName
        {
            get;
            set;
        }

    }

ダウンロードしたファイルのMethod(DownloadContentFile)を、対応するControllerの下に書きます.コードは次のとおりです.
[HttpGet]
        public HttpResponseMessage DownloadContentFile([FromUri]ContentTypeCondition entity)
        {
            string file = Path.Combine(C2Global.Server.Architect.Common.GlobalServerConfig.ProductPath, entity.PackageFileName);
            if (!FileProvider.Exists(file))
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            FileStream fileStream = FileProvider.Open(file);

            try
            {
                var response = new HttpResponseMessage();
                response.Content = new StreamContent(fileStream);
                response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
                response.Content.Headers.ContentDisposition.FileName = "test.zip";
                response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                response.Content.Headers.ContentLength = FileProvider.GetLength(file);
                return response;
            }
            catch (Exception ex)
            {
                fileStream.Close();
                return null;
            }
        }

このコードでは、まず、ファイルが存在するサーバへのパス割り当て(Path.Combine)を行い、そのファイルが存在するかどうかを判断し、存在する場合はこのファイルを読み込んでFileStreamタイプを返し、最後に返されるhttpreponsemessageを定義し、contentの内容とheaders情報を割り当てます.
ここにはFileProviderクラスがカプセル化されています.このクラスにはファイルの基本操作(ファイルが存在するかどうか、ファイルの長さ、ファイルを開くのはFileStream)が含まれています.コードは以下の通りです.
 public interface IFileProvider
        {
            bool Exists(string name);
            FileStream Open(string name);
            long GetLength(string name);
        }
        public IFileProvider FileProvider { get; set; }

        public DownloadFileController()
        {
            FileProvider = new FileProviderUtilty();
        }

        public class FileProviderUtilty : IFileProvider
        {
            private readonly string _filesDirectory;
            private string fileName = string.Empty;  

            public bool Exists(string name)
            {
                //string fileName = GetFilePath(name);
                //make sure we dont access directories outside of our store for security reasons
                bool exitsFile = File.Exists(name);
                return exitsFile;
            }

            public FileStream Open(string path)
            {                
               return File.Open(path, FileMode.Open, FileAccess.Read,FileShare.Read);                
            }

            public long GetLength(string name)
            {
                return new FileInfo(name).Length;
            }

            //private string GetFilePath(string name)
            //{
            //   string file=  ConfigurationManager.AppSettings[name];
            //   return file;
            //}
        }

これでサービス・エンド・APIは完了します
フロントエンド呼び出しプロシージャ
ここでは、ダウンロードしたファイルを転送するためのオブジェクトContentDownloadInfoDtoの情報パラメータを定義します(主にサービス側のファイルパスとクライアントがファイルを保存するパスを転送します).
具体的な呼び出し手順は次のとおりです.
/// 
        ///   product  
        /// 
        /// 
        /// 
        public virtual bool DownloadContentFile(ContentDownloadInfoDto downloadInfo)
        {
            ContentTypeCondition condition = new ContentTypeCondition();
            condition.PackageFileName = HttpUtility.UrlEncode(downloadInfo.PackageFileName, Encoding.UTF8);

            if (string.IsNullOrEmpty(condition.PackageFileName))
            {
                return false;
            }

            string url = GlobalClientConfig.BaseURI + DownloadFileWebAPI.WEB_API_NAME + "/" + DownloadFileWebAPI.DOWNLOAD_PRODUCT_PACKAGE + "/";
            Stream configFileStream = RestServiceProxy.GetFile(condition, url);

            if (configFileStream.Length == 0)
            {
                return false;
            }
            else
            {
                FileHelper.SaveFileFromStream(configFileStream, downloadInfo.TargetPackageFileName);
                return true;
            }
        }

ここではRestServiceProxy呼び出しAPIのクラスがカプセル化されており、様々なAPIへのアクセス方法が含まれている.
フロントエンドでサービス側APIを呼び出すと、Streamタイプの戻り値を取得し、カプセル化FileHelperを通過する.SaveFileFromStreamはターゲットパスの下に保存されます(TargetPackageFileName)
FileHelperコードは次のとおりです.
public class FileHelper
    {
        public static void SaveFileFromStream(Stream s, string file)
        {
            //get folder name
            string folder = file.Substring(0, file.LastIndexOf("\\"));
            if(!Directory.Exists(folder))
            {
                Directory.CreateDirectory(folder);
            }

            // Create a FileStream object to write a stream to a file
            using (FileStream fileStream = System.IO.File.Create(file, (int)s.Length))
            {
                // Fill the bytes[] array with the stream data
                byte[] bytesInStream = new byte[s.Length];
                s.Read(bytesInStream, 0, (int)bytesInStream.Length);

                // Use FileStream object to write to the specified file
                fileStream.Write(bytesInStream, 0, bytesInStream.Length);
            }
        }
    }