From b041c5fde1e114682bcbe2e4c471ae44e22a4086 Mon Sep 17 00:00:00 2001 From: Benjamin Ifland Date: Sat, 23 Mar 2019 10:29:18 +0100 Subject: [PATCH] file download --- API/API/Controllers/FilesController.cs | 35 ++++++++++++++++++++------ API/API/Services/FileService.cs | 16 ++++++++---- API/Models/File.cs | 2 ++ 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/API/API/Controllers/FilesController.cs b/API/API/Controllers/FilesController.cs index 0ac7387..8152d50 100644 --- a/API/API/Controllers/FilesController.cs +++ b/API/API/Controllers/FilesController.cs @@ -1,5 +1,8 @@ using API.Database; using API.Services; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; using System.Web; @@ -9,6 +12,7 @@ namespace API.Controllers { public class FilesController : ApiController { private readonly DataContext dataContext; private readonly IFileService fileService; + private readonly string dataPath; public FilesController( DataContext dataContext, @@ -16,29 +20,44 @@ namespace API.Controllers { ) { this.dataContext = dataContext; this.fileService = fileService; + + dataPath = System.Web.Hosting.HostingEnvironment.MapPath(@"~/App_Data"); } // GET: api/Files/5 [Route("api/songs/{songId}/files/{fileId}")] - public string Get(int id) { - return "value"; + public HttpResponseMessage Get(long songId, long fileId) { + var response = new HttpResponseMessage(HttpStatusCode.OK); + + var file = dataContext.Files.Find(fileId); + if (file == null || file.Song.ID != songId) return new HttpResponseMessage(HttpStatusCode.NotFound); + var reference = file.ReferenceFile; + var filename = file.Name; + + var stream = fileService.Load(dataPath, reference.ToString()); + response.Content = new StreamContent(stream); + response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); + response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { + FileName = filename + }; + return response; } // POST: api/Files [Route("api/songs/{songId}/files")] - public async Task Post(long songId, CancellationToken c) { + public async Task Post(long songId, CancellationToken c) { // get file from network input var files = HttpContext.Current.Request.Files; - if (files.Count != 1) return BadRequest(); + if (files.Count != 1) return new HttpResponseMessage(HttpStatusCode.BadRequest); var file = HttpContext.Current.Request.Files[0]; // find song in database var song = dataContext.Songs.Find(songId); - if (song == null) return NotFound(); + if (song == null) return new HttpResponseMessage(HttpStatusCode.NotFound); // save file in App_Data - var path = System.Web.Hosting.HostingEnvironment.MapPath(@"~/App_Data"); - var filename = await fileService.Save(file, path, c); + var stream = file.InputStream; + var filename = await fileService.Save(stream, dataPath, c); // attach file reference to song song.Files.Add(new Models.File { @@ -47,7 +66,7 @@ namespace API.Controllers { }); await dataContext.SaveChangesAsync(c); - return Ok(); + return new HttpResponseMessage(HttpStatusCode.OK); } diff --git a/API/API/Services/FileService.cs b/API/API/Services/FileService.cs index 24415bd..43c4f11 100644 --- a/API/API/Services/FileService.cs +++ b/API/API/Services/FileService.cs @@ -2,25 +2,31 @@ using System.IO; using System.Threading; using System.Threading.Tasks; -using System.Web; namespace API.Services { public interface IFileService { - Task Save(HttpPostedFile file, string path, CancellationToken c); + Task Save(Stream file, string path, CancellationToken c); + Stream Load(string path, string filename); } public class FileService : IFileService { private const int bufferSize = 4096; - public async Task Save(HttpPostedFile file, string path, CancellationToken c) { + public async Task Save(Stream inputStream, string path, CancellationToken c) { var filename = Guid.NewGuid(); var fullPath = Path.Combine(path, filename.ToString()); - using (var fs = new FileStream(fullPath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize, true)) { - await file.InputStream.CopyToAsync(fs, bufferSize, c); + using (var fileStream = new FileStream(fullPath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize, true)) { + await inputStream.CopyToAsync(fileStream, bufferSize, c); } return filename; } + + public Stream Load(string path, string filename) { + var fullPath = Path.Combine(path, filename.ToString()); + var fileStream = new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.None, bufferSize, true); + return fileStream; + } } } \ No newline at end of file diff --git a/API/Models/File.cs b/API/Models/File.cs index 5b5a496..3febd81 100644 --- a/API/Models/File.cs +++ b/API/Models/File.cs @@ -8,5 +8,7 @@ namespace API.Models { public Guid ReferenceFile { get; set; } public string Name { get; set; } public FileType FileType { get; set; } + + public virtual Song Song { get; set; } } } \ No newline at end of file