From 7e623258c02d8414422605679dc58f260574538b Mon Sep 17 00:00:00 2001 From: Kiran Challa Date: Thu, 23 Apr 2015 15:55:34 -0700 Subject: [PATCH] Use strongly typed MediaTypeHeaderValue for content type in action results. --- .../Filters/ErrorMessagesAttribute.cs | 3 +- .../ActionResults/ContentResult.cs | 42 +++++++-- .../ActionResults/FileContentResult.cs | 12 +-- .../ActionResults/FilePathResult.cs | 11 +-- .../ActionResults/FileResult.cs | 22 +++-- .../ActionResults/FileStreamResult.cs | 12 +-- .../ActionResults/PartialViewResult.cs | 8 +- .../ActionResults/ViewExecutor.cs | 44 +++++++-- .../ActionResults/ViewResult.cs | 8 +- src/Microsoft.AspNet.Mvc.Core/Controller.cs | 17 +++- .../ActionResults/ContentResultTest.cs | 90 ++++++++++++------- .../ActionResults/FileContentResultTest.cs | 25 ++++++ .../ActionResults/FilePathResultTest.cs | 35 +++++++- .../ActionResults/FileResultTest.cs | 2 +- .../ActionResults/FileStreamResultTest.cs | 30 +++++++ .../ActionResults/PartialViewResultTest.cs | 54 +++++++++++ .../ActionResults/ViewExecutorTest.cs | 70 +++++++++------ .../ActionResults/ViewResultTest.cs | 65 ++++++++++++++ .../ControllerTests.cs | 33 ++++--- .../ControllerUnitTestabilityTests.cs | 54 ++++------- .../FilePathResultTestFile_ASCII.txt | 1 + .../Filters/RandomNumberFilter.cs | 3 +- .../Filters/ShortCircuitActionFilter.cs | 3 +- .../WebSites/FiltersWebSite/Helper/Helpers.cs | 3 +- 24 files changed, 482 insertions(+), 165 deletions(-) create mode 100644 test/Microsoft.AspNet.Mvc.Core.Test/TestFiles/FilePathResultTestFile_ASCII.txt diff --git a/samples/MvcSample.Web/Filters/ErrorMessagesAttribute.cs b/samples/MvcSample.Web/Filters/ErrorMessagesAttribute.cs index e4a5f08da3..1ca581d59b 100644 --- a/samples/MvcSample.Web/Filters/ErrorMessagesAttribute.cs +++ b/samples/MvcSample.Web/Filters/ErrorMessagesAttribute.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Mvc; +using Microsoft.Net.Http.Headers; namespace MvcSample.Web { @@ -15,7 +16,7 @@ public override void OnActionExecuted(ActionExecutedContext context) context.Result = new ContentResult { - ContentType = "text/plain", + ContentType = new MediaTypeHeaderValue("text/plain"), Content = "Boom " + context.Exception.Message }; } diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ContentResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ContentResult.cs index f2de1256b9..bc4bc9e450 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ContentResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ContentResult.cs @@ -1,6 +1,8 @@ // 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.IO; using System.Text; using System.Threading.Tasks; using Microsoft.AspNet.Http; @@ -11,11 +13,20 @@ namespace Microsoft.AspNet.Mvc { public class ContentResult : ActionResult { - public string Content { get; set; } + private readonly MediaTypeHeaderValue DefaultContentType = new MediaTypeHeaderValue("text/plain") + { + Encoding = Encodings.UTF8EncodingWithoutBOM + }; - public Encoding ContentEncoding { get; set; } + /// + /// Gets or set the content representing the body of the response. + /// + public string Content { get; set; } - public string ContentType { get; set; } + /// + /// Gets or sets the representing the Content-Type header of the response. + /// + public MediaTypeHeaderValue ContentType { get; set; } /// /// Gets or sets the HTTP status code. @@ -26,17 +37,30 @@ public override async Task ExecuteResultAsync([NotNull] ActionContext context) { var response = context.HttpContext.Response; - MediaTypeHeaderValue contentTypeHeader; - if (string.IsNullOrEmpty(ContentType)) + var contentTypeHeader = ContentType; + Encoding encoding; + if (contentTypeHeader == null) { - contentTypeHeader = new MediaTypeHeaderValue("text/plain"); + contentTypeHeader = DefaultContentType; + encoding = Encodings.UTF8EncodingWithoutBOM; } else { - contentTypeHeader = new MediaTypeHeaderValue(ContentType); + if (contentTypeHeader.Encoding == null) + { + // 1. Do not modify the user supplied content type + // 2. Parse here to handle parameters apart from charset + contentTypeHeader = MediaTypeHeaderValue.Parse(contentTypeHeader.ToString()); + contentTypeHeader.Encoding = Encodings.UTF8EncodingWithoutBOM; + + encoding = Encodings.UTF8EncodingWithoutBOM; + } + else + { + encoding = contentTypeHeader.Encoding; + } } - contentTypeHeader.Encoding = ContentEncoding ?? Encodings.UTF8EncodingWithoutBOM; response.ContentType = contentTypeHeader.ToString(); if (StatusCode != null) @@ -46,7 +70,7 @@ public override async Task ExecuteResultAsync([NotNull] ActionContext context) if (Content != null) { - await response.WriteAsync(Content, contentTypeHeader.Encoding); + await response.WriteAsync(Content, encoding); } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/FileContentResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/FileContentResult.cs index bba491f3da..3fe9b2c578 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/FileContentResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/FileContentResult.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.Framework.Internal; +using Microsoft.Net.Http.Headers; namespace Microsoft.AspNet.Mvc { @@ -19,13 +20,14 @@ public class FileContentResult : FileResult /// /// Creates a new instance with - /// the provided . + /// the provided and the + /// provided . /// /// The bytes that represent the file contents. - public FileContentResult([NotNull] byte[] fileContents) - : base(contentType: null) + /// The Content-Type header of the response. + public FileContentResult([NotNull] byte[] fileContents, [NotNull] string contentType) + : this(fileContents, new MediaTypeHeaderValue(contentType)) { - FileContents = fileContents; } /// @@ -35,7 +37,7 @@ public FileContentResult([NotNull] byte[] fileContents) /// /// The bytes that represent the file contents. /// The Content-Type header of the response. - public FileContentResult([NotNull] byte[] fileContents, string contentType) + public FileContentResult([NotNull] byte[] fileContents, [NotNull] MediaTypeHeaderValue contentType) : base(contentType) { FileContents = fileContents; diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/FilePathResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/FilePathResult.cs index 3e727e576c..72e03ca2a2 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/FilePathResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/FilePathResult.cs @@ -11,6 +11,7 @@ using Microsoft.AspNet.Mvc.Core; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Internal; +using Microsoft.Net.Http.Headers; namespace Microsoft.AspNet.Mvc { @@ -27,15 +28,15 @@ public class FilePathResult : FileResult /// /// Creates a new instance with - /// the provided + /// the provided and the + /// provided . /// /// The path to the file. The path must be an absolute /// path. Relative and virtual paths are not supported. /// The Content-Type header of the response. - public FilePathResult([NotNull] string fileName) - : base(contentType: null) + public FilePathResult([NotNull] string fileName, [NotNull] string contentType) + : this(fileName, new MediaTypeHeaderValue(contentType)) { - FileName = fileName; } /// @@ -46,7 +47,7 @@ public FilePathResult([NotNull] string fileName) /// The path to the file. The path must be an absolute /// path. Relative and virtual paths are not supported. /// The Content-Type header of the response. - public FilePathResult([NotNull] string fileName, string contentType) + public FilePathResult([NotNull] string fileName, [NotNull] MediaTypeHeaderValue contentType) : base(contentType) { FileName = fileName; diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/FileResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/FileResult.cs index 0a76eb35e7..814be3e544 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/FileResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/FileResult.cs @@ -24,15 +24,25 @@ public abstract class FileResult : ActionResult /// the provided . /// /// The Content-Type header of the response. - protected FileResult(string contentType) + 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 or sets the Content-Type header value that will be written to the response. + /// Gets the representing the Content-Type header of the response. /// - public string ContentType { get; set; } + public MediaTypeHeaderValue ContentType { get; } /// /// Gets the file name that will be used in the Content-Disposition header of the response. @@ -47,11 +57,7 @@ public string FileDownloadName public override Task ExecuteResultAsync([NotNull] ActionContext context) { var response = context.HttpContext.Response; - - if (ContentType != null) - { - response.ContentType = ContentType; - } + response.ContentType = ContentType.ToString(); if (!string.IsNullOrEmpty(FileDownloadName)) { diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/FileStreamResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/FileStreamResult.cs index 28b8e8a1d8..68c932c227 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/FileStreamResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/FileStreamResult.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.Framework.Internal; +using Microsoft.Net.Http.Headers; namespace Microsoft.AspNet.Mvc { @@ -23,13 +24,14 @@ public class FileStreamResult : FileResult /// /// Creates a new instance with - /// the provided . + /// the provided and the + /// provided . /// /// The stream with the file. - public FileStreamResult([NotNull] Stream fileStream) - : base(contentType: null) + /// The Content-Type header of the response. + public FileStreamResult([NotNull] Stream fileStream, [NotNull] string contentType) + : this(fileStream, new MediaTypeHeaderValue(contentType)) { - FileStream = fileStream; } /// @@ -39,7 +41,7 @@ public FileStreamResult([NotNull] Stream fileStream) /// /// The stream with the file. /// The Content-Type header of the response. - public FileStreamResult([NotNull] Stream fileStream, string contentType) + public FileStreamResult([NotNull] Stream fileStream, [NotNull] MediaTypeHeaderValue contentType) : base(contentType) { FileStream = fileStream; diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/PartialViewResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/PartialViewResult.cs index d7045e3b56..36c06b855c 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/PartialViewResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/PartialViewResult.cs @@ -7,6 +7,7 @@ using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; +using Microsoft.Net.Http.Headers; namespace Microsoft.AspNet.Mvc { @@ -45,6 +46,11 @@ public class PartialViewResult : ActionResult /// ActionContext.HttpContext.RequestServices is used. public IViewEngine ViewEngine { get; set; } + /// + /// Gets or sets the representing the Content-Type header of the response. + /// + public MediaTypeHeaderValue ContentType { get; set; } + /// public override async Task ExecuteResultAsync([NotNull] ActionContext context) { @@ -74,7 +80,7 @@ public override async Task ExecuteResultAsync([NotNull] ActionContext context) using (view as IDisposable) { - await ViewExecutor.ExecuteAsync(view, context, ViewData, TempData, contentType: null); + await ViewExecutor.ExecuteAsync(view, context, ViewData, TempData, ContentType); } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewExecutor.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewExecutor.cs index 1cf47cc753..8d0d049d53 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewExecutor.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewExecutor.cs @@ -1,10 +1,13 @@ // 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.IO; +using System.Text; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.Rendering; using Microsoft.Framework.Internal; +using Microsoft.Net.Http.Headers; namespace Microsoft.AspNet.Mvc { @@ -14,7 +17,10 @@ namespace Microsoft.AspNet.Mvc public static class ViewExecutor { private const int BufferSize = 1024; - private const string ContentType = "text/html; charset=utf-8"; + private static readonly MediaTypeHeaderValue DefaultContentType = new MediaTypeHeaderValue("text/html") + { + Encoding = Encodings.UTF8EncodingWithoutBOM + }; /// /// Asynchronously renders the specified to the response body. @@ -23,21 +29,43 @@ public static class ViewExecutor /// The for the current executing action. /// The for the view being rendered. /// The for the view being rendered. - /// A that represents the asychronous rendering. + /// A that represents the asynchronous rendering. public static async Task ExecuteAsync([NotNull] IView view, [NotNull] ActionContext actionContext, [NotNull] ViewDataDictionary viewData, [NotNull] ITempDataDictionary tempData, - string contentType) + MediaTypeHeaderValue contentType) { - if (string.IsNullOrEmpty(contentType)) + var response = actionContext.HttpContext.Response; + + var contentTypeHeader = contentType; + Encoding encoding; + if (contentTypeHeader == null) { - contentType = ContentType; + contentTypeHeader = DefaultContentType; + encoding = Encodings.UTF8EncodingWithoutBOM; } + else + { + if (contentTypeHeader.Encoding == null) + { + // 1. Do not modify the user supplied content type + // 2. Parse here to handle parameters apart from charset + contentTypeHeader = MediaTypeHeaderValue.Parse(contentTypeHeader.ToString()); + contentTypeHeader.Encoding = Encodings.UTF8EncodingWithoutBOM; + + encoding = Encodings.UTF8EncodingWithoutBOM; + } + else + { + encoding = contentTypeHeader.Encoding; + } + } + + response.ContentType = contentTypeHeader.ToString(); + + var wrappedStream = new StreamWrapper(response.Body); - actionContext.HttpContext.Response.ContentType = contentType; - var wrappedStream = new StreamWrapper(actionContext.HttpContext.Response.Body); - var encoding = Encodings.UTF8EncodingWithoutBOM; using (var writer = new StreamWriter(wrappedStream, encoding, BufferSize, leaveOpen: true)) { try diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs index a0bd1cae49..a29f87bbf0 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs @@ -7,6 +7,7 @@ using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; +using Microsoft.Net.Http.Headers; namespace Microsoft.AspNet.Mvc { @@ -45,6 +46,11 @@ public class ViewResult : ActionResult /// ActionContext.HttpContext.RequestServices is used. public IViewEngine ViewEngine { get; set; } + /// + /// Gets or sets the representing the Content-Type header of the response. + /// + public MediaTypeHeaderValue ContentType { get; set; } + /// public override async Task ExecuteResultAsync([NotNull] ActionContext context) { @@ -74,7 +80,7 @@ public override async Task ExecuteResultAsync([NotNull] ActionContext context) using (view as IDisposable) { - await ViewExecutor.ExecuteAsync(view, context, ViewData, TempData, contentType: null); + await ViewExecutor.ExecuteAsync(view, context, ViewData, TempData, ContentType); } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/Controller.cs b/src/Microsoft.AspNet.Mvc.Core/Controller.cs index 4143a6acdf..2cf4f110da 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Controller.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Controller.cs @@ -14,6 +14,7 @@ using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Routing; using Microsoft.Framework.Internal; +using Microsoft.Net.Http.Headers; namespace Microsoft.AspNet.Mvc { @@ -330,7 +331,7 @@ public virtual PartialViewResult PartialView(string viewName, object model) [NonAction] public virtual ContentResult Content(string content) { - return Content(content, contentType: null); + return Content(content, (MediaTypeHeaderValue)null); } /// @@ -356,11 +357,23 @@ public virtual ContentResult Content(string content, string contentType) /// The created object for the response. [NonAction] public virtual ContentResult Content(string content, string contentType, Encoding contentEncoding) + { + return Content(content, new MediaTypeHeaderValue(contentType) { Encoding = contentEncoding }); + } + + /// + /// Creates a object by specifying a + /// string and a . + /// + /// The content to write to the response. + /// The content type (MIME type). + /// The created object for the response. + [NonAction] + public virtual ContentResult Content(string content, MediaTypeHeaderValue contentType) { var result = new ContentResult { Content = content, - ContentEncoding = contentEncoding, ContentType = contentType }; diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ContentResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ContentResultTest.cs index 0b5e56f797..b1b3ae6ebc 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ContentResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ContentResultTest.cs @@ -1,11 +1,12 @@ // 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.IO; using System.Text; using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Routing; +using Microsoft.Net.Http.Headers; using Moq; using Xunit; @@ -20,8 +21,7 @@ public async Task ContentResult_Response_NullEncoding_SetsContentTypeAndDefaultE var contentResult = new ContentResult { Content = "Test Content", - ContentType = "application/json", - ContentEncoding = null + ContentType = new MediaTypeHeaderValue("application/json") }; var httpContext = GetHttpContext(); var actionContext = GetActionContext(httpContext); @@ -40,8 +40,10 @@ public async Task ContentResult_Response_SetsContentTypeAndEncoding() var contentResult = new ContentResult { Content = "Test Content", - ContentType = "text/plain", - ContentEncoding = Encoding.ASCII + ContentType = new MediaTypeHeaderValue("text/plain") + { + Encoding = Encoding.ASCII + } }; var httpContext = GetHttpContext(); var actionContext = GetActionContext(httpContext); @@ -54,14 +56,16 @@ public async Task ContentResult_Response_SetsContentTypeAndEncoding() } [Fact] - public async Task ContentResult_Response_NullContentType_SetsEncodingAndDefaultContentType() + public async Task ContentResult_Response_NullContent_SetsContentTypeAndEncoding() { // Arrange var contentResult = new ContentResult { - Content = "Test Content", - ContentType = null, - ContentEncoding = Encoding.UTF7 + Content = null, + ContentType = new MediaTypeHeaderValue("text/plain") + { + Encoding = Encoding.UTF7 + } }; var httpContext = GetHttpContext(); var actionContext = GetActionContext(httpContext); @@ -73,45 +77,65 @@ public async Task ContentResult_Response_NullContentType_SetsEncodingAndDefaultC Assert.Equal("text/plain; charset=utf-7", httpContext.Response.ContentType); } - [Fact] - public async Task ContentResult_Response_NullContent_SetsContentTypeAndEncoding() + public static TheoryData ContentResultContentTypeData { - // Arrange - var contentResult = new ContentResult + get { - Content = null, - ContentType = "application/json", - ContentEncoding = Encoding.UTF8 - }; - var httpContext = GetHttpContext(); - var actionContext = GetActionContext(httpContext); - - // Act - await contentResult.ExecuteResultAsync(actionContext); - - // Assert - Assert.Equal("application/json; charset=utf-8", httpContext.Response.ContentType); + return new TheoryData + { + { + null, + "κόσμε", + "text/plain; charset=utf-8", + new byte[] { 206, 186, 225, 189, 185, 207, 131, 206, 188, 206, 181 } //utf-8 without BOM + }, + { + new MediaTypeHeaderValue("text/foo"), + "κόσμε", + "text/foo; charset=utf-8", + new byte[] { 206, 186, 225, 189, 185, 207, 131, 206, 188, 206, 181 } //utf-8 without BOM + }, + { + MediaTypeHeaderValue.Parse("text/foo;p1=p1-value"), + "κόσμε", + "text/foo; p1=p1-value; charset=utf-8", + new byte[] { 206, 186, 225, 189, 185, 207, 131, 206, 188, 206, 181 } //utf-8 without BOM + }, + { + new MediaTypeHeaderValue("text/foo") { Encoding = Encoding.ASCII }, + "abcd", + "text/foo; charset=us-ascii", + new byte[] { 97, 98, 99, 100 } + } + }; + } } - [Fact] - public async Task ContentResult_Response_BadContentType_ThrowsFormatException() + [Theory] + [MemberData(nameof(ContentResultContentTypeData))] + public async Task ContentResult_ExecuteResultAsync_SetContentTypeAndEncoding_OnResponse( + MediaTypeHeaderValue contentType, + string content, + string expectedContentType, + byte[] expectedContentData) { // Arrange var contentResult = new ContentResult { - Content = "Test Content", - ContentType = "some-type", - ContentEncoding = null + Content = content, + ContentType = contentType }; var httpContext = GetHttpContext(); + var memoryStream = new MemoryStream(); + httpContext.Response.Body = memoryStream; var actionContext = GetActionContext(httpContext); // Act - var exception = await Assert.ThrowsAsync( - async () => await contentResult.ExecuteResultAsync(actionContext)); + await contentResult.ExecuteResultAsync(actionContext); // Assert - Assert.Equal("Invalid media type 'some-type'.", exception.Message); + Assert.Equal(expectedContentType, httpContext.Response.ContentType); + Assert.Equal(expectedContentData, memoryStream.ToArray()); } private static ActionContext GetActionContext(HttpContext httpContext) diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/FileContentResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/FileContentResultTest.cs index ae4037f03b..a53aec0c34 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/FileContentResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/FileContentResultTest.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Routing; +using Microsoft.Net.Http.Headers; using Xunit; namespace Microsoft.AspNet.Mvc @@ -45,5 +46,29 @@ public async Task WriteFileAsync_CopiesBuffer_ToOutputStream() // Assert Assert.Equal(buffer, outStream.ToArray()); } + + [Fact] + public async Task ExecuteResultAsync_SetsSuppliedContentTypeAndEncoding() + { + // Arrange + var expectedContentType = "text/foo; charset=us-ascii"; + var buffer = new byte[] { 1, 2, 3, 4, 5 }; + + var httpContext = new DefaultHttpContext(); + + var outStream = new MemoryStream(); + httpContext.Response.Body = outStream; + + var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); + + var result = new FileContentResult(buffer, MediaTypeHeaderValue.Parse(expectedContentType)); + + // Act + await result.ExecuteResultAsync(context); + + // Assert + Assert.Equal(buffer, outStream.ToArray()); + Assert.Equal(expectedContentType, httpContext.Response.ContentType); + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/FilePathResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/FilePathResultTest.cs index 651aecdc4b..80342a13da 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/FilePathResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/FilePathResultTest.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.IO; +using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNet.FileProviders; @@ -9,9 +10,9 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Routing; using Microsoft.Framework.DependencyInjection; +using Microsoft.Net.Http.Headers; using Moq; using Xunit; -using System.Text; namespace Microsoft.AspNet.Mvc { @@ -111,6 +112,36 @@ public async Task ExecuteResultAsync_CallsSendFileAsync_IfIHttpSendFilePresent() sendFileMock.Verify(); } + [Fact] + public async Task ExecuteResultAsync_SetsSuppliedContentTypeAndEncoding() + { + // Arrange + var expectedContentType = "text/foo; charset=us-ascii"; + // path will be C:/.../TestFiles/FilePathResultTestFile_ASCII.txt + var path = Path.GetFullPath(Path.Combine(".", "TestFiles", "FilePathResultTestFile_ASCII.txt")); + path = path.Replace(@"\", "/"); + + // Point the FileProviderRoot to a subfolder + var result = new FilePathResult(path, MediaTypeHeaderValue.Parse(expectedContentType)) + { + FileProvider = new PhysicalFileProvider(Path.GetFullPath("Utils")), + }; + + var httpContext = new DefaultHttpContext(); + var memoryStream = new MemoryStream(); + httpContext.Response.Body = memoryStream; + + var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); + + // Act + await result.ExecuteResultAsync(context); + + // Assert + var contents = Encoding.ASCII.GetString(memoryStream.ToArray()); + Assert.Equal("FilePathResultTestFile contents ASCII encoded", contents); + Assert.Equal(expectedContentType, httpContext.Response.ContentType); + } + [Fact] public async Task ExecuteResultAsync_WorksWithAbsolutePaths_UsingBackSlash() { @@ -186,7 +217,7 @@ public async Task ExecuteResultAsync_WorksWithNonDiskBasedFiles() nonDiskFileInfo.Setup(fi => fi.CreateReadStream()).Returns(sourceStream); var nonDiskFileProvider = new Mock(); nonDiskFileProvider.Setup(fp => fp.GetFileInfo(It.IsAny())).Returns(nonDiskFileInfo.Object); - var filePathResult = new FilePathResult("/SampleEmbeddedFile.txt") + var filePathResult = new FilePathResult("/SampleEmbeddedFile.txt", "text/plain") { FileProvider = nonDiskFileProvider.Object }; diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/FileResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/FileResultTest.cs index 4c818ffac4..281a25f2bb 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/FileResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/FileResultTest.cs @@ -22,7 +22,7 @@ public void Constructor_SetsContentType() var result = new EmptyFileResult("text/plain"); // Assert - Assert.Equal("text/plain", result.ContentType); + Assert.Equal("text/plain", result.ContentType.ToString()); } [Fact] diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/FileStreamResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/FileStreamResultTest.cs index b08597819e..1be9797f29 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/FileStreamResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/FileStreamResultTest.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Routing; +using Microsoft.Net.Http.Headers; using Moq; using Xunit; @@ -87,5 +88,34 @@ public async Task WriteFileAsync_CopiesProvidedStream_ToOutputStream() var outBytes = outStream.ToArray(); Assert.True(originalBytes.SequenceEqual(outBytes)); } + + [Fact] + public async Task SetsSuppliedContentTypeAndEncoding() + { + // Arrange + var expectedContentType = "text/foo; charset=us-ascii"; + // Generate an array of bytes with a predictable pattern + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, 10, 11, 12, 13 + var originalBytes = Enumerable.Range(0, 0x1234) + .Select(b => (byte)(b % 20)).ToArray(); + + var originalStream = new MemoryStream(originalBytes); + + var httpContext = new DefaultHttpContext(); + var outStream = new MemoryStream(); + httpContext.Response.Body = outStream; + + var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); + + var result = new FileStreamResult(originalStream, MediaTypeHeaderValue.Parse(expectedContentType)); + + // Act + await result.ExecuteResultAsync(actionContext); + + // Assert + var outBytes = outStream.ToArray(); + Assert.True(originalBytes.SequenceEqual(outBytes)); + Assert.Equal(expectedContentType, httpContext.Response.ContentType); + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/PartialViewResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/PartialViewResultTest.cs index 65c181cd83..310bada677 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/PartialViewResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/PartialViewResultTest.cs @@ -2,11 +2,13 @@ // 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.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Routing; using Microsoft.Framework.Logging; +using Microsoft.Net.Http.Headers; using Moq; using Xunit; @@ -69,6 +71,58 @@ public async Task ViewResult_UsesFindPartialViewOnSpecifiedViewEngineToLocateVie viewEngine.Verify(); } + public static TheoryData PartialViewResultContentTypeData + { + get + { + return new TheoryData + { + { + null, + "text/html; charset=utf-8" + }, + { + new MediaTypeHeaderValue("text/foo"), + "text/foo; charset=utf-8" + }, + { + new MediaTypeHeaderValue("text/foo") { Encoding = Encoding.ASCII }, + "text/foo; charset=us-ascii" + } + }; + } + } + + [Theory] + [MemberData(nameof(PartialViewResultContentTypeData))] + public async Task PartialViewResult_SetsContentTypeHeader( + MediaTypeHeaderValue contentType, + string expectedContentTypeHeaderValue) + { + // Arrange + var viewName = "myview"; + var httpContext = GetHttpContext(); + var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); + var viewEngine = new Mock(); + var view = Mock.Of(); + + viewEngine.Setup(e => e.FindPartialView(context, "myview")) + .Returns(ViewEngineResult.Found("myview", view)); + + var viewResult = new PartialViewResult + { + ViewName = viewName, + ViewEngine = viewEngine.Object, + ContentType = contentType + }; + + // Act + await viewResult.ExecuteResultAsync(context); + + // Assert + Assert.Equal(expectedContentTypeHeaderValue, httpContext.Response.ContentType); + } + [Fact] public async Task ExecuteResultAsync_UsesActionDescriptorName_IfViewNameIsNull() { diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ViewExecutorTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ViewExecutorTest.cs index b63d53e150..0af2c87812 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ViewExecutorTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ViewExecutorTest.cs @@ -4,11 +4,13 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Routing; +using Microsoft.Net.Http.Headers; using Moq; using Xunit; @@ -19,12 +21,44 @@ public class ViewExecutorTest // The buffer size of the StreamWriter used in ViewResult. private const int ViewResultStreamWriterBufferSize = 1024; - [Fact] - public async Task ExecuteAsync_WritesOutputWithoutBOM() + public static TheoryData ViewExecutorSetsContentTypeAndEncodingData { - // Arrange - var expected = new byte[] { 97, 98, 99, 100 }; + get + { + return new TheoryData + { + { + null, + "text/html; charset=utf-8", + new byte[] { 97, 98, 99, 100 } + }, + { + new MediaTypeHeaderValue("text/foo"), + "text/foo; charset=utf-8", + new byte[] { 97, 98, 99, 100 } + }, + { + MediaTypeHeaderValue.Parse("text/foo; p1=p1-value"), + "text/foo; p1=p1-value; charset=utf-8", + new byte[] { 97, 98, 99, 100 } + }, + { + new MediaTypeHeaderValue("text/foo") { Charset = "us-ascii" }, + "text/foo; charset=us-ascii", + new byte[] { 97, 98, 99, 100 } + } + }; + } + } + [Theory] + [MemberData(nameof(ViewExecutorSetsContentTypeAndEncodingData))] + public async Task ExecuteAsync_SetsContentTypeAndEncoding( + MediaTypeHeaderValue contentType, + string expectedContentType, + byte[] expectedContentData) + { + // Arrange var view = new Mock(); view.Setup(v => v.RenderAsync(It.IsAny())) .Callback((ViewContext v) => @@ -44,33 +78,11 @@ public async Task ExecuteAsync_WritesOutputWithoutBOM() var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); // Act - await ViewExecutor.ExecuteAsync(view.Object, actionContext, viewData, null, contentType: null); - - // Assert - Assert.Equal(expected, memoryStream.ToArray()); - Assert.Equal("text/html; charset=utf-8", context.Response.ContentType); - } - - [Fact] - public async Task ExecuteAsync_UsesSpecifiedContentType() - { - // Arrange - var contentType = "some-content-type"; - var view = Mock.Of(); - var context = new DefaultHttpContext(); - var memoryStream = new MemoryStream(); - context.Response.Body = memoryStream; - - var actionContext = new ActionContext(context, - new RouteData(), - new ActionDescriptor()); - var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); - - // Act - await ViewExecutor.ExecuteAsync(view, actionContext, viewData, null, contentType); + await ViewExecutor.ExecuteAsync(view.Object, actionContext, viewData, null, contentType); // Assert - Assert.Equal(contentType, context.Response.ContentType); + Assert.Equal(expectedContentType, context.Response.ContentType); + Assert.Equal(expectedContentData, memoryStream.ToArray()); } public static IEnumerable ExecuteAsync_DoesNotWriteToResponse_OnceExceptionIsThrownData diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ViewResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ViewResultTest.cs index bebd512a76..66f51d5e48 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ViewResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ViewResultTest.cs @@ -2,11 +2,13 @@ // 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.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Routing; using Microsoft.Framework.Logging; +using Microsoft.Net.Http.Headers; using Moq; using Xunit; @@ -70,6 +72,69 @@ public async Task ViewResult_UsesFindViewOnSpecifiedViewEngineToLocateViews() viewEngine.Verify(); } + public static TheoryData ViewResultContentTypeData + { + get + { + return new TheoryData + { + { + null, + "text/html; charset=utf-8" + }, + { + new MediaTypeHeaderValue("text/foo"), + "text/foo; charset=utf-8" + }, + { + MediaTypeHeaderValue.Parse("text/foo;p1=p1-value"), + "text/foo; p1=p1-value; charset=utf-8" + }, + { + new MediaTypeHeaderValue("text/foo") { Encoding = Encoding.ASCII }, + "text/foo; charset=us-ascii" + } + }; + } + } + + [Theory] + [MemberData(nameof(ViewResultContentTypeData))] + public async Task ViewResult_SetsContentTypeHeader( + MediaTypeHeaderValue contentType, + string expectedContentTypeHeaderValue) + { + // Arrange + var viewName = "myview"; + var httpContext = GetHttpContext(); + var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); + var viewEngine = new Mock(); + var view = Mock.Of(); + var contentTypeBeforeViewResultExecution = contentType?.ToString(); + + viewEngine.Setup(e => e.FindView(context, "myview")) + .Returns(ViewEngineResult.Found("myview", view)); + + var viewResult = new ViewResult + { + ViewName = viewName, + ViewEngine = viewEngine.Object, + ContentType = contentType + }; + + // Act + await viewResult.ExecuteResultAsync(context); + + // Assert + Assert.Equal(expectedContentTypeHeaderValue, httpContext.Response.ContentType); + + // Check if the original instance provided by the user has not changed. + // Since we do not have access to the new instance created within the view executor, + // check if at least the content is the same. + var contentTypeAfterViewResultExecution = contentType?.ToString(); + Assert.Equal(contentTypeBeforeViewResultExecution, contentTypeAfterViewResultExecution); + } + [Fact] public async Task ExecuteResultAsync_UsesActionDescriptorName_IfViewNameIsNull() { diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ControllerTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ControllerTests.cs index ad4cbca215..df565d3788 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ControllerTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ControllerTests.cs @@ -627,12 +627,12 @@ public void File_WithContents() var fileContents = new byte[0]; // Act - var result = controller.File(fileContents, "someContentType"); + var result = controller.File(fileContents, "application/pdf"); // Assert Assert.NotNull(result); Assert.Same(fileContents, result.FileContents); - Assert.Equal("someContentType", result.ContentType); + Assert.Equal("application/pdf", result.ContentType.ToString()); Assert.Equal(string.Empty, result.FileDownloadName); } @@ -644,12 +644,12 @@ public void File_WithContentsAndFileDownloadName() var fileContents = new byte[0]; // Act - var result = controller.File(fileContents, "someContentType", "someDownloadName"); + var result = controller.File(fileContents, "application/pdf", "someDownloadName"); // Assert Assert.NotNull(result); Assert.Same(fileContents, result.FileContents); - Assert.Equal("someContentType", result.ContentType); + Assert.Equal("application/pdf", result.ContentType.ToString()); Assert.Equal("someDownloadName", result.FileDownloadName); } @@ -661,12 +661,12 @@ public void File_WithPath() var path = Path.GetFullPath("somepath"); // Act - var result = controller.File(path, "someContentType"); + var result = controller.File(path, "application/pdf"); // Assert Assert.NotNull(result); Assert.Equal(path, result.FileName); - Assert.Equal("someContentType", result.ContentType); + Assert.Equal("application/pdf", result.ContentType.ToString()); Assert.Equal(string.Empty, result.FileDownloadName); } @@ -678,12 +678,12 @@ public void File_WithPathAndFileDownloadName() var path = Path.GetFullPath("somepath"); // Act - var result = controller.File(path, "someContentType", "someDownloadName"); + var result = controller.File(path, "application/pdf", "someDownloadName"); // Assert Assert.NotNull(result); Assert.Equal(path, result.FileName); - Assert.Equal("someContentType", result.ContentType); + Assert.Equal("application/pdf", result.ContentType.ToString()); Assert.Equal("someDownloadName", result.FileDownloadName); } @@ -700,12 +700,12 @@ public void File_WithStream() var fileStream = Stream.Null; // Act - var result = controller.File(fileStream, "someContentType"); + var result = controller.File(fileStream, "application/pdf"); // Assert Assert.NotNull(result); Assert.Same(fileStream, result.FileStream); - Assert.Equal("someContentType", result.ContentType); + Assert.Equal("application/pdf", result.ContentType.ToString()); Assert.Equal(string.Empty, result.FileDownloadName); } @@ -723,12 +723,12 @@ public void File_WithStreamAndFileDownloadName() var fileStream = Stream.Null; // Act - var result = controller.File(fileStream, "someContentType", "someDownloadName"); + var result = controller.File(fileStream, "application/pdf", "someDownloadName"); // Assert Assert.NotNull(result); Assert.Same(fileStream, result.FileStream); - Assert.Equal("someContentType", result.ContentType); + Assert.Equal("application/pdf", result.ContentType.ToString()); Assert.Equal("someDownloadName", result.FileDownloadName); mockHttpContext.Verify( x => x.Response.OnResponseCompleted(It.IsAny>(), It.IsAny()), @@ -980,7 +980,6 @@ public void Controller_Content_WithParameterContentString_SetsResultContent() // Assert Assert.IsType(actualContentResult); Assert.Equal("TestContent", actualContentResult.Content); - Assert.Null(actualContentResult.ContentEncoding); Assert.Null(actualContentResult.ContentType); } @@ -996,8 +995,8 @@ public void Controller_Content_WithParameterContentStringAndContentType_SetsResu // Assert Assert.IsType(actualContentResult); Assert.Equal("TestContent", actualContentResult.Content); - Assert.Null(actualContentResult.ContentEncoding); - Assert.Equal("text/plain", actualContentResult.ContentType); + Assert.Null(actualContentResult.ContentType.Encoding); + Assert.Equal("text/plain", actualContentResult.ContentType.ToString()); } [Fact] @@ -1012,8 +1011,8 @@ public void Controller_Content_WithParameterContentAndTypeAndEncoding_SetsResult // Assert Assert.IsType(actualContentResult); Assert.Equal("TestContent", actualContentResult.Content); - Assert.Same(Encoding.UTF8, actualContentResult.ContentEncoding); - Assert.Equal("text/plain", actualContentResult.ContentType); + Assert.Same(Encoding.UTF8, actualContentResult.ContentType.Encoding); + Assert.Equal("text/plain; charset=utf-8", actualContentResult.ContentType.ToString()); } [Fact] diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ControllerUnitTestabilityTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ControllerUnitTestabilityTests.cs index 12a9ade0f5..dcf85863ad 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ControllerUnitTestabilityTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ControllerUnitTestabilityTests.cs @@ -71,11 +71,13 @@ public void ControllerPartialView_InvokedInUnitTests(object model, string viewNa } } - [Theory] - [MemberData(nameof(TestabilityContentTestData))] - public void ControllerContent_InvokedInUnitTests(string content, string contentType, Encoding encoding) + [Fact] + public void ControllerContent_InvokedInUnitTests() { // Arrange + var content = "Content_1"; + var contentType = "text/asp"; + var encoding = Encoding.ASCII; var controller = new TestabilityController(); // Act @@ -86,8 +88,8 @@ public void ControllerContent_InvokedInUnitTests(string content, string contentT var contentResult = Assert.IsType(result); Assert.Equal(content, contentResult.Content); - Assert.Equal(contentType, contentResult.ContentType); - Assert.Equal(encoding, contentResult.ContentEncoding); + Assert.Equal("text/asp; charset=us-ascii", contentResult.ContentType.ToString()); + Assert.Equal(encoding, contentResult.ContentType.Encoding); } [Theory] @@ -110,12 +112,13 @@ public void ControllerCreated_InvokedInUnitTests(string uri, string content) Assert.Equal(StatusCodes.Status201Created, createdResult.StatusCode); } - [Theory] - [InlineData("CreatedBody", "text/html", "Created.html")] - [InlineData("CreatedBody", null, null)] - public void ControllerFileContent_InvokedInUnitTests(string content, string contentType, string fileName) + [Fact] + public void ControllerFileContent_InvokedInUnitTests() { // Arrange + var content = "CreatedBody"; + var contentType = "text/html"; + var fileName = "Created.html"; var controller = new TestabilityController(); // Act @@ -125,7 +128,7 @@ public void ControllerFileContent_InvokedInUnitTests(string content, string cont Assert.NotNull(result); var fileContentResult = Assert.IsType(result); - Assert.Equal(contentType, fileContentResult.ContentType); + Assert.Equal(contentType, fileContentResult.ContentType.ToString()); Assert.Equal(fileName ?? string.Empty, fileContentResult.FileDownloadName); if (content == null) @@ -138,12 +141,13 @@ public void ControllerFileContent_InvokedInUnitTests(string content, string cont } } - [Theory] - [InlineData("CreatedBody", "text/html", "Created.html")] - [InlineData("CreatedBody", null, null)] - public void ControllerFileStream_InvokedInUnitTests(string content, string contentType, string fileName) + [Fact] + public void ControllerFileStream_InvokedInUnitTests() { // Arrange + var content = "CreatedBody"; + var contentType = "text/html"; + var fileName = "Created.html"; var mockHttpContext = new Mock(); mockHttpContext.Setup(x => x.Response.OnResponseCompleted(It.IsAny>(), It.IsAny())); var controller = new TestabilityController() @@ -158,7 +162,7 @@ public void ControllerFileStream_InvokedInUnitTests(string content, string conte Assert.NotNull(result); var fileStreamResult = Assert.IsType(result); - Assert.Equal(contentType, fileStreamResult.ContentType); + Assert.Equal(contentType, fileStreamResult.ContentType.ToString()); Assert.Equal(fileName ?? string.Empty, fileStreamResult.FileDownloadName); if (content == null) @@ -547,26 +551,6 @@ public static IEnumerable TestabilityViewTestData } } - public static IEnumerable TestabilityContentTestData - { - get - { - yield return new object[] - { - null, - null, - null - }; - - yield return new object[] - { - "Content_1", - "text/asp", - Encoding.ASCII - }; - } - } - private class TestabilityController : Controller { public IActionResult View_Action(string viewName, object data) diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/TestFiles/FilePathResultTestFile_ASCII.txt b/test/Microsoft.AspNet.Mvc.Core.Test/TestFiles/FilePathResultTestFile_ASCII.txt new file mode 100644 index 0000000000..bde72f59aa --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.Core.Test/TestFiles/FilePathResultTestFile_ASCII.txt @@ -0,0 +1 @@ +FilePathResultTestFile contents ASCII encoded \ No newline at end of file diff --git a/test/WebSites/FiltersWebSite/Filters/RandomNumberFilter.cs b/test/WebSites/FiltersWebSite/Filters/RandomNumberFilter.cs index be2442ea32..9d21ed60cd 100644 --- a/test/WebSites/FiltersWebSite/Filters/RandomNumberFilter.cs +++ b/test/WebSites/FiltersWebSite/Filters/RandomNumberFilter.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Mvc; +using Microsoft.Net.Http.Headers; namespace FiltersWebSite { @@ -12,7 +13,7 @@ public void OnActionExecuted(ActionExecutedContext context) context.Result = new ContentResult() { Content = "4", - ContentType = "text/plain" + ContentType = new MediaTypeHeaderValue("text/plain") }; } diff --git a/test/WebSites/FiltersWebSite/Filters/ShortCircuitActionFilter.cs b/test/WebSites/FiltersWebSite/Filters/ShortCircuitActionFilter.cs index 2484619bef..3a2831b5f6 100644 --- a/test/WebSites/FiltersWebSite/Filters/ShortCircuitActionFilter.cs +++ b/test/WebSites/FiltersWebSite/Filters/ShortCircuitActionFilter.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Mvc; +using Microsoft.Net.Http.Headers; namespace FiltersWebSite { @@ -12,7 +13,7 @@ public override void OnActionExecuting(ActionExecutingContext context) context.Result = new ContentResult { Content = "The Action was never executed", - ContentType = "text/plain" + ContentType = new MediaTypeHeaderValue("text/plain") }; } } diff --git a/test/WebSites/FiltersWebSite/Helper/Helpers.cs b/test/WebSites/FiltersWebSite/Helper/Helpers.cs index 828dcb2479..897d5088f2 100644 --- a/test/WebSites/FiltersWebSite/Helper/Helpers.cs +++ b/test/WebSites/FiltersWebSite/Helper/Helpers.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Mvc; +using Microsoft.Net.Http.Headers; namespace FiltersWebSite { @@ -20,7 +21,7 @@ public static ContentResult GetContentResult(object result, string message) return new ContentResult() { Content = content, - ContentType = "text/plain", + ContentType = new MediaTypeHeaderValue("text/plain"), }; } }