ASP.NET本质论
上QQ阅读APP看书,第一时间看更新

2.5.5 自定义的请求参数对象

现在,上传文件过程已经被我们接管了,上传的文件将被保存在我们指定的位置。在下面的实现中,通过System.IO.Path的静态方法GetTempFileName在系统的临时文件目录中创建一个文件,在上传过程中上传的文件将被保存在这里。为了能够访问这个文件的信息,必须自定义表示上传文件的类型。

为了表示自定义的请求参数,下面创建了FileItem用于表示一个上传文件对象。实现过程见代码清单2-3。

代码清单2-3 自定义的请求参数类型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DiskFileUpload
{
    public class FileItem:System.IDisposable
    {
        public System.IO.Stream Stream { get; private set; }
        public string ContentType { get; private set; }
        public string Name { get; private set; }
        public string Value{ get; set;}
        public bool IsFormField { get; private set; }
        public string ClientFullPath { get; private set; }
        public string TempFullPath { get; private set; }
        //构造函数
        public FileItem(string name, bool isForm, string path, string contentType)
        {
            this.Name = name;
            this.IsFormField = isForm;
            this.ClientFullPath = path;
            this.ContentType = contentType;
            if (!this.IsFormField)
            {
                //创建临时文件
                this.TempFullPath = System.IO.Path.GetTempFileName();
                this.Stream = new System.IO.FileStream(
                    this.TempFullPath,
                    System.IO.FileMode.Create
                   );
            }
        }
        public string FileName
        {
            get
            {
                return System.IO.Path.GetFileName(this.ClientFullPath);
             }
        }
        public long Length
        {
            get
            {
                System.IO.FileInfo fi = new System.IO.FileInfo(this.TempFullPath);
                return fi.Length;
             }
        }
        //另存为
        public void SaveAs(string path)
        {
            System.IO.File.Copy(
                this.TempFullPath,
                path
               );
        }
        //删除临时文件
        public void Delete()
        {
            if (System.IO.File.Exists(this.TempFullPath))
            {
                System.IO.File.Delete(this.TempFullPath);
             }
        }
        public string ToContentString(string boundary)
        {
            System.Text.StringBuilder builder = new StringBuilder();
            builder.AppendFormat("\r\nContent-Disposition:form-data;
                name=\"{0}\"", this.Name);
            if (this.IsFormField)
            {
                builder.Append("\r\n\r\n");
                builder.AppendFormat("{0}",this.Value);
            }
            else
            {
                builder.AppendFormat("; filename=\"{0}\"\r\n",
                    this.ClientFullPath);
                builder.Append("Content-Type:application/octet-stream\r\n");
                builder.Append("\r\n");
            }
            builder.Append(boundary);
            return builder.ToString();
        }
        public void Finish()
        {
            if(this.Stream != null)
                this.Stream.Close();
        }
        #region IDisposable Members
        public void Dispose()
        {
            if (this.Stream != null)
            {
                this.Stream.Dispose();
            }
            this.Delete();
        }
        #endregion
    }
}

在一个表单中也可能同时上传多个文件,多个参数通过UploadFiles表示,见代码清单2-4。

代码清单2-4 多个参数的表示类型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
namespace DiskFileUpload
{
    public class UploadFiles :System.Collections.CollectionBase,
        System.IDisposable
    {
        public static readonly string DiskFileUpload_GUID = "DiskFileUpload_GUID";
        private NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
        public string ApplicationKey{ get; set; }
        private int completePercent = 0;
        public int CompletePercent
        {
            get { return this.completePercent; }
        }
        public void CompletePercentHander(object sender,
            HttpWorkerFileUploadEventArgs e)
        {
            this.completePercent = (int)(e.Position * 100 /e.Length);
            this.logger.Trace("Percent:{0}",
                    this.completePercent
              );
        }
        public int Add(FileItem item)
        {
            return this.List.Add(item);
        }
        public void Insert(int index, FileItem value)
        {
            List.Insert(index, value);
        }
        public void Remove(FileItem value)
        {
            List.Remove(value);
        }
        public FileItem this[int index]
        {
            get
            {
                return ((FileItem)List[index]);
            }
            set
            {
                List[index] = value;
            }
        }
        public string ToContentString(string boundary)
        {
            boundary = "\r\n--"+ boundary;
            System.Text.StringBuilder builder = new StringBuilder();
            builder.Append(boundary.Substring(2));
            foreach (FileItem item in this.List)
            {
                builder.Append(item.ToContentString(boundary));
            }
            builder.Append("--\r\n");
            return builder.ToString();
        }
        #region IDisposable Members
        public void Dispose()
        {
            foreach (FileItem item in this)
            {
                item.Dispose();
            }
            HttpContext context = HttpContext.Current;
            if (context != null)
            {
                HttpApplicationState application = context.Application;
                application.Remove(UploadFiles.DiskFileUpload_GUID);
            }
        }
        #endregion
    }
}