// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.Framework.Internal; using Microsoft.Net.Http.Headers; namespace Microsoft.AspNet.Mvc { /// /// Represents an that when executed will /// write a file as the response. /// public abstract class FileResult : ActionResult { private string _fileDownloadName; /// /// Creates a new instance with /// the provided . /// /// The Content-Type header of the response. protected FileResult([NotNull] string contentType) : this(new MediaTypeHeaderValue(contentType)) { } /// /// Creates a new instance with /// the provided . /// /// The Content-Type header of the response. protected FileResult([NotNull] MediaTypeHeaderValue contentType) { ContentType = contentType; } /// /// Gets the representing the Content-Type header of the response. /// public MediaTypeHeaderValue ContentType { get; } /// /// Gets the file name that will be used in the Content-Disposition header of the response. /// public string FileDownloadName { get { return _fileDownloadName ?? string.Empty; } set { _fileDownloadName = value; } } /// public override Task ExecuteResultAsync([NotNull] ActionContext context) { var response = context.HttpContext.Response; response.ContentType = ContentType.ToString(); if (!string.IsNullOrEmpty(FileDownloadName)) { // From RFC 2183, Sec. 2.3: // The sender may want to suggest a filename to be used if the entity is // detached and stored in a separate file. If the receiving MUA writes // the entity to a file, the suggested filename should be used as a // basis for the actual filename, where possible. var cd = new ContentDispositionHeaderValue("attachment"); cd.SetHttpFileName(FileDownloadName); context.HttpContext.Response.Headers.Set(HeaderNames.ContentDisposition, cd.ToString()); } // We aren't flowing the cancellation token appropriately, see // https://github.com/aspnet/Mvc/issues/743 for details. return WriteFileAsync(response, CancellationToken.None); } /// /// Writes the file to the response. /// /// /// The where the file will be written /// /// The to cancel the operation. /// /// A that will complete when the file has been written to the response. /// protected abstract Task WriteFileAsync(HttpResponse response, CancellationToken cancellation); } }