// 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.Threading.Tasks; using Microsoft.AspNet.Http; 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(string contentType) : this(new MediaTypeHeaderValue(contentType)) { if (contentType == null) { throw new ArgumentNullException(nameof(contentType)); } } /// /// Creates a new instance with /// the provided . /// /// The Content-Type header of the response. protected FileResult(MediaTypeHeaderValue contentType) { if (contentType == null) { throw new ArgumentNullException(nameof(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(ActionContext context) { if (context == null) { throw new ArgumentNullException(nameof(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[HeaderNames.ContentDisposition] = cd.ToString(); } return WriteFileAsync(response); } /// /// Writes the file to the specified . /// /// The . /// /// A that will complete when the file has been written to the response. /// protected abstract Task WriteFileAsync(HttpResponse response); } }