Bootstrap
本文主要介绍ASP.NET Web API中,实现文件上传和文件下载,以及图片查看代码,并且支持FTP存储。

1、配置文件Web.config

<appSettings>
 <!--FileService-->
    <add key="ftpUserName" value="fooUserName" />
    <add key="ftpPassword" value="fooPass" />
<!--FileController-->
    <add key="fileServiceLocalPath" value="~/App_Data/Upload" />
    <add key="fileServiceStoragePath" value="fooFtpAddress" />
    <add key="useCloud" value="false" />
</appSettings>

2、文件上传下载图片查看FileController

实现文件上传、文件下载、图片查看的Controller(控制器)。

[Authorize]
[RoutePrefix("api/File")]
 public class FileController : ApiController
    {
        IFileService fileService = null;
        public FileController(IFileService _fileService)
        {
            fileService = _fileService;
        }
        [Route("Upload"), HttpPost]
        public async Task<IHttpActionResult> Upload()
        {
            #region Condition
            if (!Request.Content.IsMimeMultipartContent())
                return Content(HttpStatusCode.UnsupportedMediaType, Messages.FUW0001);
            #endregion
            /// `localPath` 和 `useCloud` 是在 Web.Config中获取.
            string localPath = HostingEnvironment.MapPath(ConfigurationManager.AppSettings["fileServiceLocalPath"]);
            bool useCloud = Convert.ToBoolean(ConfigurationManager.AppSettings["useCloud"]);
            var provider = new MultipartFormDataStreamProvider(localPath);
            try
            {
                /// 载入文件在本地存储
                await Request.Content.ReadAsMultipartAsync(provider);
                /// 检查是否存在有效的文件
                if (provider.FileData.Count == 0)
                    return BadRequest(Messages.FUE0001 /*Message Type FUE001 = File Not Found */);
                IList<FileDto> modelList = new List<FileDto>();
                foreach (MultipartFileData file in provider.FileData)
                {
                    string originalName = file.Headers.ContentDisposition.FileName;
                    if (originalName.StartsWith("\"") && originalName.EndsWith("\""))
                    {
                        originalName = originalName.Trim('"');
                    }
                    if (originalName.Contains(@"/") || originalName.Contains(@"\"))
                    {
                        originalName = Path.GetFileName(originalName);
                    }
                    /// 文件信息存储到数据库
                    FileDto fileDto = new FileDto
                    {
                        OriginalName = Path.GetFileNameWithoutExtension(originalName),
                        StorageName = Path.GetFileName(file.LocalFileName),
                        Extension = Path.GetExtension(originalName).ToLower().Replace(".", ""),
                        Size = new FileInfo(file.LocalFileName).Length
                    };
                    modelList.Add(fileDto);
                }
                if (useCloud)
                    await fileService.SendCloud(modelList,localPath);
                await fileService.Add(modelList, IdentityClaimsValues.UserID<Guid>());
                return Ok(Messages.Ok);
            }
            catch (Exception exMessage)
            {
                return Content(HttpStatusCode.InternalServerError, exMessage);
            }
        }
        [Route("Download"), HttpGet]
        public async Task<IHttpActionResult> Download(Guid id)
        {
            ///获取文件信息从数据库
            var model = await fileService.GetByID(id);
            if (model == null)
                return BadRequest();
            /// `localPath` 在 Web.Config中.
            string localPath = HostingEnvironment.MapPath(ConfigurationManager.AppSettings["fileServiceLocalPath"]);
            string root = localPath + "\\" + model.StorageName;
            byte[] fileData = File.ReadAllBytes(root);
            var stream = new MemoryStream(fileData, 0, fileData.Length);
            var response = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new ByteArrayContent(stream.ToArray())
            };
            response.Content.Headers.ContentDisposition =
                new ContentDispositionHeaderValue("attachment")
                {
                    FileName = model.OriginalName + "." + model.Extension,
                    Size=model.Size
                };
            response.Content.Headers.ContentType =
                new MediaTypeHeaderValue("application/octet-stream");
            IHttpActionResult result = ResponseMessage(response);
            return result;
        }
        [Route("ImageReview"), HttpGet]
        public async Task<IHttpActionResult> ImageReview(Guid id)
        {
            /// 获取文件信息从数据库
            var model = await fileService.GetByID(id);
            if (model == null)
                return BadRequest();
            /// `localPath` 在 Web.Config中.
            string localPath = HostingEnvironment.MapPath(ConfigurationManager.AppSettings["fileServiceLocalPath"]);
            string root = localPath + "\\" + model.StorageName;
            byte[] fileData = File.ReadAllBytes(root);
            var stream = new MemoryStream(fileData, 0, fileData.Length);
            var response = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StreamContent(stream)
            };
            response.Content.Headers.ContentType =
                new MediaTypeHeaderValue("image/"+ model.Extension);
            IHttpActionResult result = ResponseMessage(response);
            return result;
        }
    }

3、将文件存储到FTP的FileService类

实现将服务器本地文件传输到FTP服务器

public interface IFileService
    {
        Task SendCloud(IList<FileDto> modelList, string localPath);
    }   
    public class FileService : IFileService
    {
        public Task SendCloud(IList<FileDto> modelList,string localPath)
        {
            /// `ftpUserName`, `ftpPassword` 和 `storagePath` 在 Web.Config中获取.
            string ftpUserName = ConfigurationManager.AppSettings["ftpUserName"];
            string ftpPassword = ConfigurationManager.AppSettings["ftpPassword"];
            string storagePath = ConfigurationManager.AppSettings["fileServiceStoragePath"];
            /// 上传文件到FTP服务器
            foreach (var model in modelList)
            {
                FtpWebRequest req = (FtpWebRequest)WebRequest.Create(storagePath + model.StorageName);
                req.UseBinary = true;
                req.Method = WebRequestMethods.Ftp.UploadFile;
                req.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
                byte[] fileData = File.ReadAllBytes(localPath + "\\" + model.StorageName);
                req.ContentLength = fileData.Length;
                Stream reqStream = req.GetRequestStream();
                reqStream.Write(fileData, 0, fileData.Length);
                reqStream.Close();
            }
            return Task.CompletedTask;
        }
    }