Download
The IDownloadHelper service contains helper methods which make it easier to handle conditional requests and range requests. It is automatically registered when the AddCoreMvcServices() method is called (see the MVC chapter for more information).
NOTE
Even though the built-in File() method implemented by controllers can handle both conditional requests and range requests, it is not very efficient when the file is dynamically generated or downloaded from an external storage. When using this method, the entire file has to be always downloaded beforehand, even if a 304 Not Modified response or a 206 Partial Content response is returned.
The CheckPrecondition() method handles conditional request headers, including:
If-MatchIf-None-MatchIf-Modified-SinceIf-Unmodified-Since
It automatically generates a 412 Precondition Failed response or a 304 Not Modified response and returns false if further processing of the request should be skipped. The ETag and Last-Modified headers are automatically added to the response.
The CheckPreconditionAndRange() method works the same as CheckPrecondition(), but it also handles the Range and If-Range request headers.
In addition to the responses generated by CheckPrecondition(), it also automatically generates a 416 Range Not Satisfiable response. It returns false if further processing of the request should be skipped. Otherwise it returns the normalized range or null if the full response should be returned.
The ETag, Last-Modified, Accept-Ranges, Content-Range and Content-Length headers are automatically added to the response, and the status code is set to 206 Partial Content when a range is returned.
The following example code shows how this service can be used by a controller (in combination with IStorageService described in the Storage chapter):
if ( !_downloadHelper.CheckPreconditionAndRange( HttpContext, tag, lastModified, length, out var range ) )
return Empty;
Response.Headers.CacheControl = "no-cache, private";
var stream = await _storageService.DownloadAsStreamAsync( fileName, range );
return File( stream, mediaType, fileName );