WebAPI文件上传与下载
项目预览:
webApi文件上传与下载
支持多文件批量上传
文件在服务器端以GUID重命名存储
上传后返回文件信息
上传接口控制器:
public class FilesController : ApiController { public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } private const string UploadFolder = "uploads"; public HttpResponseMessage Get(string fileName) { HttpResponseMessage result = null; DirectoryInfo directoryInfo = new DirectoryInfo(HostingEnvironment.MapPath("~/App_Data/" + UploadFolder)); FileInfo foundFileInfo = directoryInfo.GetFiles().Where(x => x.Name == fileName).FirstOrDefault(); if (foundFileInfo != null) { FileStream fs = new FileStream(foundFileInfo.FullName, FileMode.Open); result = new HttpResponseMessage(HttpStatusCode.OK); result.Content = new StreamContent(fs); result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"); result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); result.Content.Headers.ContentDisposition.FileName = foundFileInfo.Name; } else { result = new HttpResponseMessage(HttpStatusCode.NotFound); } return result; } public Task<IQueryable<HDFile>> Post() { try { //uploadFolderPath variable determines where the files should be temporarily uploaded into server. //Remember to give full control permission to IUSER so that IIS can write file to that folder. string uploadFolderPath = HostingEnvironment.MapPath("~/App_Data/" + UploadFolder); //如果路径不存在,创建路径 if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath); //#region CleaningUpPreviousFiles.InDevelopmentOnly //DirectoryInfo directoryInfo = new DirectoryInfo(uploadFolderPath); //foreach (FileInfo fileInfo in directoryInfo.GetFiles()) // fileInfo.Delete(); //#endregion if (Request.Content.IsMimeMultipartContent()) //If the request is correct, the binary data will be extracted from content and IIS stores files in specified location. { var streamProvider = new WithExtensionMultipartFormDataStreamProvider(uploadFolderPath); var task = Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith<IQueryable<HDFile>>(t => { if (t.IsFaulted || t.IsCanceled) { throw new HttpResponseException(HttpStatusCode.InternalServerError); } var fileInfo = streamProvider.FileData.Select(i => { var info = new FileInfo(i.LocalFileName); return new HDFile(info.Name, string.Format("{0}?filename={1}", Request.RequestUri.AbsoluteUri, info.Name), (info.Length / 1024).ToString()); }); return fileInfo.AsQueryable(); }); return task; } else { throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted")); } } catch (Exception ex) { throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message)); } } public class HDFile { public HDFile(string name, string url, string size) { Name = name; Url = url; Size = size; } public string Name { get; set; } public string Url { get; set; } public string Size { get; set; } } }
public class WithExtensionMultipartFormDataStreamProvider : MultipartFormDataStreamProvider { public WithExtensionMultipartFormDataStreamProvider(string rootPath) : base(rootPath) { } public override string GetLocalFileName(System.Net.Http.Headers.HttpContentHeaders headers) { string extension = !string.IsNullOrWhiteSpace(headers.ContentDisposition.FileName) ? Path.GetExtension(GetValidFileName(headers.ContentDisposition.FileName)) : ""; return Guid.NewGuid().ToString() + extension; } private string GetValidFileName(string filePath) { char[] invalids = System.IO.Path.GetInvalidFileNameChars(); return String.Join("_", filePath.Split(invalids, StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.'); } }
客户端
界面:
public class ServerFileHelper { private readonly string api = "http://localhost:6841/api/files"; public ServerFileHelper(string apiurl) { api = apiurl; } public IEnumerable<HDFile> UploadFiles(params string[] FullFileNames) { Uri server = new Uri(api); HttpClient httpClient = new HttpClient(); MultipartFormDataContent multipartFormDataContent = new MultipartFormDataContent(); foreach (string fullfilename in FullFileNames) { string filename = Path.GetFileName(fullfilename); string filenameWithoutExtension = Path.GetFileNameWithoutExtension(fullfilename); //这里会向服务器上传一个png图片和一个txt文件 StreamContent streamConent = new StreamContent(new FileStream(fullfilename, FileMode.Open, FileAccess.Read, FileShare.Read)); multipartFormDataContent.Add(streamConent, filenameWithoutExtension, filename); } HttpResponseMessage responseMessage = httpClient.PostAsync(server, multipartFormDataContent).Result; if (responseMessage.IsSuccessStatusCode) { IList<HDFile> hdFiles=null; string content = responseMessage.Content.ReadAsStringAsync().Result; hdFiles = Newtonsoft.Json.JsonConvert.DeserializeObject<IList<HDFile>>(content); if (hdFiles.Count > 0) return hdFiles; else return null; } return null; } public bool DownLoad(string ServerFileName, string SaveFileName) { Uri server = new Uri(String.Format("{0}?filename={1}", api, ServerFileName)); HttpClient httpClient = new HttpClient(); string p = Path.GetDirectoryName(SaveFileName); if (!Directory.Exists(p)) Directory.CreateDirectory(p); HttpResponseMessage responseMessage = httpClient.GetAsync(server).Result; if (responseMessage.IsSuccessStatusCode) { using (FileStream fs = File.Create(SaveFileName)) { Stream streamFromService = responseMessage.Content.ReadAsStreamAsync().Result; streamFromService.CopyTo(fs); return true; } } else return false; } }
git项目源码地址:
慎于行,敏于思!GGGGGG