Reputation: 27
I'm creating a REST service using C#/MVC/WebAPI that will allow access to a file server. The two main operations will be uploading a file or downloading a file. I need to expose the service to mobile devices (Android and Apple) and web browsers on Window and Apple.
I can't seem to find any good guidelines or best practices on how functionality like this should be designed. I've only built REST services before that have used JSON for data being passed in or being returned. I see examples for C# but then they're consumed by C# client code. I feel like with files being involved platform specifics start being important, but I can't find any information that backs that up. Maybe I'm overthinking it.
What I'm looking for is advice or links to information that outline standards for uploading and downloading files over rest. For example, as long as you accept a file in the POST call for upload, is that enough (leave it up to the client to figure out how to post that file)? How much metadata should I upload with the file, if any? Is the best way to download a file via a GET call to have the call return a url to the file? Are there any other "gotchas" I should be aware of?
Upvotes: 1
Views: 1266
Reputation: 21881
I suspect you are over thinking it, uploading and downloading file is pretty standard HTTP stuff, nothing platform specific about it. Below are example upload and download web api actions I wrote a while ago, which hopefully will point you in the right direction.
[Route("api/upload/")]
[HttpPost]
public async Task<IHttpActionResult> Upload()
{
if (!Request.Content.IsMimeMultipartContent())
{
return StatusCode(HttpStatusCode.UnsupportedMediaType);
}
var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider);
var file = provider.Contents.FirstOrDefault();
if (file == null)
{
return BadRequest("No file found");
}
var fileStream = await file.ReadAsStreamAsync();
// Do something with thte filestream
return Ok();
}
[Route("api/download/{id}")]
[HttpGet]
public async Task<IHttpActionResult> Download(Guid id)
{
if (id == default(Guid))
{
return NotFound();
}
var file = await SomeAsynchMethod(id); // returns custom File type.
if (file == null)
{
return NotFound();
}
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(file.FileDataBytes)
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue(file.FileType);
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attatchment")
{
FileName = file.FileName
};
return ResponseMessage(result);
}
Upvotes: 2