web API file downloading in chunks from SQL server
web API file downloading in chunks from SQL server
I want download File from Sqlserver in Chunks and respond it to my client using pushstreamcontent or streamcontent from my web API. What is the correct approach to achieve this?
I have two approaches in my mind
1 Answer
1
I believe this should get you through:
public HttpResponseMessage Get([FromUri]string filename)
string path = HttpContext.Current.Server.MapPath("~/" + filename);
if (!File.Exists(path))
throw new HttpResponseException("The file does not exist.", HttpStatusCode.NotFound);
try
MemoryStream responseStream = new MemoryStream();
Stream fileStream = File.Open(path, FileMode.Open);
bool fullContent = true;
if (this.Request.Headers.Range != null)
fullContent = false;
// Currently we only support a single range.
RangeItemHeaderValue range = this.Request.Headers.Range.Ranges.First();
// From specified, so seek to the requested position.
if (range.From != null)
fileStream.Seek(range.From.Value, SeekOrigin.Begin);
// In this case, actually the complete file will be returned.
if (range.From == 0 && (range.To == null
if (range.To != null)
// 10-20, return the range.
if (range.From != null)
long? rangeLength = range.To - range.From;
int length = (int)Math.Min(rangeLength.Value, fileStream.Length - range.From.Value);
byte buffer = new byte[length];
fileStream.Read(buffer, 0, length);
responseStream.Write(buffer, 0, length);
// -20, return the bytes from beginning to the specified value.
else
int length = (int)Math.Min(range.To.Value, fileStream.Length);
byte buffer = new byte[length];
fileStream.Read(buffer, 0, length);
responseStream.Write(buffer, 0, length);
// No Range.To
else
// 10-, return from the specified value to the end of file.
if (range.From != null)
if (range.From < fileStream.Length)
int length = (int)(fileStream.Length - range.From.Value);
byte buffer = new byte[length];
fileStream.Read(buffer, 0, length);
responseStream.Write(buffer, 0, length);
// No Range header. Return the complete file.
else
fileStream.CopyTo(responseStream);
fileStream.Close();
responseStream.Position = 0;
HttpResponseMessage response = new HttpResponseMessage();
response.StatusCode = fullContent ? HttpStatusCode.OK : HttpStatusCode.PartialContent;
response.Content = new StreamContent(responseStream);
return response;
catch (IOException)
throw new HttpResponseException("A generic error occured. Please try again later.", HttpStatusCode.InternalServerError);
Note when using Web API, you don't need to manually parse the Range header in the form of text. Web API automatically parses it for you, and gives you a From and a To property for each range. The type of From and To is Nullable, as those properties can be null (think bytes=-100 and bytes=300-). Those special cases must be handled carefully.
Another special case to consider is where To is larger than the resource size. In this case, it is equivalent to To is null, where you need to return starting with From to the end of the resource.
If the complete resource is returned, usually status code is set to 200 OK. If only part of the resource is returned, usually status code is set to 206 PartialContent.
This solution is part of the article here which covers a lot of other things and I encourage you to check it out: https://blogs.msdn.microsoft.com/codefx/2012/02/23/more-about-rest-file-upload-download-service-with-asp-net-web-api-and-windows-phone-background-file-transfer/
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.