/// <summary>
        /// Redirects the client to the specified file.
        /// </summary>
        public void ReturnFile(Stream stream, string fileName, string mimeType, IHeaderDictionary additionalHeaders = null)
        {
            var returnedFileStorage = Configuration.ServiceLocator.GetService <IReturnedFileStorage>();
            var metadata            = new ReturnedFileMetadata()
            {
                FileName          = fileName,
                MimeType          = mimeType,
                AdditionalHeaders = additionalHeaders?.ToDictionary(k => k.Key, k => k.Value)
            };

            var generatedFileId = returnedFileStorage.StoreFile(stream, metadata).Result;

            RedirectToUrl("~/dotvvmReturnedFile?id=" + generatedFileId);
        }
        /// <summary>
        /// Redirects the client to the specified file.
        /// </summary>
        public void ReturnFile(byte[] bytes, string fileName, string mimeType, IEnumerable <KeyValuePair <string, string> > additionalHeaders = null)
        {
            var returnedFileStorage = Configuration.ServiceLocator.GetService <IReturnedFileStorage>();
            var metadata            = new ReturnedFileMetadata()
            {
                FileName          = fileName,
                MimeType          = mimeType,
                AdditionalHeaders = additionalHeaders?.GroupBy(k => k.Key, k => k.Value)?.ToDictionary(k => k.Key, k => k.ToArray())
            };

            var generatedFileId = returnedFileStorage.StoreFile(bytes, metadata).Result;

            RedirectToUrl("~/dotvvmReturnedFile?id=" + generatedFileId);
        }
        /// <summary>
        /// Redirects the client to the specified file.
        /// </summary>
        public static void ReturnFile(this IDotvvmRequestContext context, Stream stream, string fileName, string mimeType, IEnumerable <KeyValuePair <string, string> > additionalHeaders = null)
        {
            var returnedFileStorage = context.Services.GetService <IReturnedFileStorage>();
            var metadata            = new ReturnedFileMetadata()
            {
                FileName          = fileName,
                MimeType          = mimeType,
                AdditionalHeaders = additionalHeaders?.GroupBy(k => k.Key, k => k.Value)?.ToDictionary(k => k.Key, k => k.ToArray())
            };

            var generatedFileId = returnedFileStorage.StoreFile(stream, metadata).Result;

            context.SetRedirectResponse(context.TranslateVirtualPath("~/dotvvmReturnedFile?id=" + generatedFileId));
            throw new DotvvmInterruptRequestExecutionException(InterruptReason.ReturnFile, fileName);
        }
    /// <summary>
    /// Redirects the client to the specified file.
    /// </summary>
    public static void ReturnFile(this IDotvvmRequestContext context, Stream stream, string fileName, string mimeType, IEnumerable <KeyValuePair <string, string> > additionalHeaders = null)
    {
        var returnedFileStorage = context.Services.GetService <IReturnedFileStorage>();

        if (returnedFileStorage == null)
        {
            throw new DotvvmFileStorageMissingException($"Unable to resolve service for type '{typeof(IReturnedFileStorage).Name}'. " +
                                                        $"Visit https://www.dotvvm.com/docs/tutorials/advanced-returning-files for more details!");
        }

        var metadata = new ReturnedFileMetadata()
        {
            FileName          = fileName,
            MimeType          = mimeType,
            AdditionalHeaders = additionalHeaders?.GroupBy(k => k.Key, k => k.Value)?.ToDictionary(k => k.Key, k => k.ToArray())
        };

        var generatedFileId = returnedFileStorage.StoreFile(stream, metadata).Result;

        context.SetRedirectResponse(context.TranslateVirtualPath("~/dotvvmReturnedFile?id=" + generatedFileId));
        throw new DotvvmInterruptRequestExecutionException(InterruptReason.ReturnFile, fileName);
    }