[Fixes #3433] Invalid media type 'text/plain; charset=utf-8'

This commit is contained in:
Kiran Challa 2015-11-17 09:32:05 -08:00
parent 4bcf236450
commit 31e42ee312
13 changed files with 166 additions and 26 deletions

View File

@ -1,6 +1,6 @@
{
"commands": {
"web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:5001",
"web": "Microsoft.AspNet.Server.Kestrel",
"kestrel": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel --server.urls http://localhost:5000"
},
"compilationOptions": {

View File

@ -25,7 +25,7 @@ namespace Microsoft.AspNet.Mvc
/// <param name="fileContents">The bytes that represent the file contents.</param>
/// <param name="contentType">The Content-Type header of the response.</param>
public FileContentResult(byte[] fileContents, string contentType)
: this(fileContents, new MediaTypeHeaderValue(contentType))
: this(fileContents, MediaTypeHeaderValue.Parse(contentType))
{
if (fileContents == null)
{

View File

@ -19,20 +19,6 @@ namespace Microsoft.AspNet.Mvc
{
private string _fileDownloadName;
/// <summary>
/// Creates a new <see cref="FileResult"/> instance with
/// the provided <paramref name="contentType"/>.
/// </summary>
/// <param name="contentType">The Content-Type header of the response.</param>
protected FileResult(string contentType)
: this(new MediaTypeHeaderValue(contentType))
{
if (contentType == null)
{
throw new ArgumentNullException(nameof(contentType));
}
}
/// <summary>
/// Creates a new <see cref="FileResult"/> instance with
/// the provided <paramref name="contentType"/>.
@ -87,7 +73,7 @@ namespace Microsoft.AspNet.Mvc
contentDisposition.SetHttpFileName(FileDownloadName);
context.HttpContext.Response.Headers[HeaderNames.ContentDisposition] = contentDisposition.ToString();
}
logger.FileResultExecuting(FileDownloadName);
return WriteFileAsync(response);
}

View File

@ -30,7 +30,7 @@ namespace Microsoft.AspNet.Mvc
/// <param name="fileStream">The stream with the file.</param>
/// <param name="contentType">The Content-Type header of the response.</param>
public FileStreamResult(Stream fileStream, string contentType)
: this(fileStream, new MediaTypeHeaderValue(contentType))
: this(fileStream, MediaTypeHeaderValue.Parse(contentType))
{
}

View File

@ -28,7 +28,7 @@ namespace Microsoft.AspNet.Mvc
/// <param name="fileName">The path to the file. The path must be an absolute path.</param>
/// <param name="contentType">The Content-Type header of the response.</param>
public PhysicalFileResult(string fileName, string contentType)
: this(fileName, new MediaTypeHeaderValue(contentType))
: this(fileName, MediaTypeHeaderValue.Parse(contentType))
{
if (fileName == null)
{

View File

@ -31,7 +31,7 @@ namespace Microsoft.AspNet.Mvc
/// <param name="fileName">The path to the file. The path must be relative/virtual.</param>
/// <param name="contentType">The Content-Type header of the response.</param>
public VirtualFileResult(string fileName, string contentType)
: this(fileName, new MediaTypeHeaderValue(contentType))
: this(fileName, MediaTypeHeaderValue.Parse(contentType))
{
if (fileName == null)
{

View File

@ -467,7 +467,7 @@ namespace Microsoft.AspNet.Mvc
[NonAction]
public virtual ContentResult Content(string content, string contentType)
{
return Content(content, contentType, contentEncoding: null);
return Content(content, MediaTypeHeaderValue.Parse(contentType));
}
/// <summary>
@ -478,10 +478,16 @@ namespace Microsoft.AspNet.Mvc
/// <param name="contentType">The content type (MIME type).</param>
/// <param name="contentEncoding">The content encoding.</param>
/// <returns>The created <see cref="ContentResult"/> object for the response.</returns>
/// <remarks>
/// If encoding is provided by both the 'charset' and the <paramref name="contentEncoding"/> parameters, then
/// the <paramref name="contentEncoding"/> parameter is chosen as the final encoding.
/// </remarks>
[NonAction]
public virtual ContentResult Content(string content, string contentType, Encoding contentEncoding)
{
return Content(content, new MediaTypeHeaderValue(contentType) { Encoding = contentEncoding });
var mediaTypeHeaderValue = MediaTypeHeaderValue.Parse(contentType);
mediaTypeHeaderValue.Encoding = contentEncoding ?? mediaTypeHeaderValue.Encoding;
return Content(content, mediaTypeHeaderValue);
}
/// <summary>
@ -639,7 +645,7 @@ namespace Microsoft.AspNet.Mvc
}
/// <summary>
/// Creates a <see cref="LocalRedirectResult"/> object with <see cref="LocalRedirectResult.Permanent"/>
/// Creates a <see cref="LocalRedirectResult"/> object with <see cref="LocalRedirectResult.Permanent"/>
/// set to true using the specified <paramref name="localUrl"/>.
/// </summary>
/// <param name="localUrl">The local URL to redirect to.</param>
@ -1756,7 +1762,7 @@ namespace Microsoft.AspNet.Mvc
{
throw new ArgumentNullException(nameof(model));
}
var modelName = prefix ?? string.Empty;
// Clear ModelStateDictionary entries for the model so that it will be re-validated.

View File

@ -31,6 +31,22 @@ namespace Microsoft.AspNet.Mvc
Assert.Same(fileContents, result.FileContents);
}
[Fact]
public void Constructor_SetsContentTypeAndParameters()
{
// Arrange
var fileContents = new byte[0];
var contentType = "text/plain; charset=us-ascii; p1=p1-value";
var expectedMediaType = MediaTypeHeaderValue.Parse(contentType);
// Act
var result = new FileContentResult(fileContents, contentType);
// Assert
Assert.Same(fileContents, result.FileContents);
Assert.Equal(expectedMediaType, result.ContentType);
}
[Fact]
public async Task WriteFileAsync_CopiesBuffer_ToOutputStream()
{

View File

@ -275,12 +275,12 @@ namespace Microsoft.AspNet.Mvc
public bool WasWriteFileCalled;
public EmptyFileResult()
: this(MediaTypeNames.Application.Octet)
: base(MediaTypeHeaderValue.Parse(MediaTypeNames.Application.Octet))
{
}
public EmptyFileResult(string contentType)
: base(contentType)
: base(MediaTypeHeaderValue.Parse(contentType))
{
}

View File

@ -35,6 +35,22 @@ namespace Microsoft.AspNet.Mvc
Assert.Equal(stream, result.FileStream);
}
[Fact]
public void Constructor_SetsContentTypeAndParameters()
{
// Arrange
var stream = Stream.Null;
var contentType = "text/plain; charset=us-ascii; p1=p1-value";
var expectedMediaType = MediaTypeHeaderValue.Parse(contentType);
// Act
var result = new FileStreamResult(stream, contentType);
// Assert
Assert.Equal(stream, result.FileStream);
Assert.Equal(expectedMediaType, result.ContentType);
}
[Fact]
public async Task WriteFileAsync_WritesResponse_InChunksOfFourKilobytes()
{

View File

@ -35,6 +35,22 @@ namespace Microsoft.AspNet.Mvc
Assert.Equal(path, result.FileName);
}
[Fact]
public void Constructor_SetsContentTypeAndParameters()
{
// Arrange
var path = Path.GetFullPath("helllo.txt");
var contentType = "text/plain; charset=us-ascii; p1=p1-value";
var expectedMediaType = MediaTypeHeaderValue.Parse(contentType);
// Act
var result = new PhysicalFileResult(path, contentType);
// Assert
Assert.Equal(path, result.FileName);
Assert.Equal(expectedMediaType, result.ContentType);
}
[Fact]
public async Task ExecuteResultAsync_FallsbackToStreamCopy_IfNoIHttpSendFilePresent()
{

View File

@ -36,6 +36,22 @@ namespace Microsoft.AspNet.Mvc
Assert.Equal(path, result.FileName);
}
[Fact]
public void Constructor_SetsContentTypeAndParameters()
{
// Arrange
var path = Path.GetFullPath("helllo.txt");
var contentType = "text/plain; charset=us-ascii; p1=p1-value";
var expectedMediaType = MediaTypeHeaderValue.Parse(contentType);
// Act
var result = new VirtualFileResult(path, contentType);
// Assert
Assert.Equal(path, result.FileName);
Assert.Equal(expectedMediaType, result.ContentType);
}
[Fact]
public async Task ExecuteResultAsync_FallsBackToWebRootFileProvider_IfNoFileProviderIsPresent()
{

View File

@ -18,6 +18,7 @@ using Microsoft.AspNet.Mvc.ModelBinding.Validation;
using Microsoft.AspNet.Mvc.ViewFeatures;
using Microsoft.AspNet.Routing;
using Microsoft.AspNet.Testing;
using Microsoft.Net.Http.Headers;
using Moq;
using Newtonsoft.Json;
using Xunit;
@ -1107,6 +1108,66 @@ namespace Microsoft.AspNet.Mvc.Test
Assert.Equal("text/plain; charset=utf-8", actualContentResult.ContentType.ToString());
}
[Fact]
public void Controller_Content_NoContentType_DefaultEncodingIsUsed()
{
// Arrange
var contentController = new ContentController();
var expected = MediaTypeHeaderValue.Parse("text/plain; charset=utf-8");
// Act
var contentResult = (ContentResult)contentController.Content_WithNoEncoding();
// Assert
// The default content type of ContentResult is used when the result is executed.
Assert.Null(contentResult.ContentType);
}
[Fact]
public void Controller_Content_InvalidCharset_DefaultEncodingIsUsed()
{
// Arrange
var contentController = new ContentController();
var contentType = "text/xml; charset=invalid; p1=p1-value";
// Act
var contentResult = (ContentResult)contentController.Content_WithInvalidCharset();
// Assert
Assert.NotNull(contentResult.ContentType);
Assert.Equal(contentType, contentResult.ContentType.ToString());
// The default encoding of ContentResult is used when this result is executed.
Assert.Null(contentResult.ContentType.Encoding);
}
[Fact]
public void Controller_Content_CharsetAndEncodingProvided_EncodingIsUsed()
{
// Arrange
var contentController = new ContentController();
var contentType = MediaTypeHeaderValue.Parse("text/xml; charset=us-ascii; p1=p1-value");
// Act
var contentResult = (ContentResult)contentController.Content_WithEncodingInCharset_AndEncodingParameter();
// Assert
Assert.Equal(contentType, contentResult.ContentType);
}
[Fact]
public void Controller_Content_CharsetInContentType_IsUsedForEncoding()
{
// Arrange
var contentController = new ContentController();
var contentType = MediaTypeHeaderValue.Parse("text/xml; charset=us-ascii; p1=p1-value");
// Act
var contentResult = (ContentResult)contentController.Content_WithEncodingInCharset();
// Assert
Assert.Equal(contentType, contentResult.ContentType);
}
[Fact]
public void Controller_Json_WithParameterValue_SetsResultData()
{
@ -1883,6 +1944,29 @@ namespace Microsoft.AspNet.Mvc.Test
throw new NotImplementedException();
}
}
private class ContentController : Controller
{
public IActionResult Content_WithNoEncoding()
{
return Content("Hello!!");
}
public IActionResult Content_WithEncodingInCharset()
{
return Content("Hello!!", "text/xml; charset=us-ascii; p1=p1-value");
}
public IActionResult Content_WithInvalidCharset()
{
return Content("Hello!!", "text/xml; charset=invalid; p1=p1-value");
}
public IActionResult Content_WithEncodingInCharset_AndEncodingParameter()
{
return Content("Hello!!", "text/xml; charset=invalid; p1=p1-value", Encoding.ASCII);
}
}
}
}