Use strongly typed MediaTypeHeaderValue for content type in action results.
This commit is contained in:
parent
38bd617778
commit
7e623258c0
|
|
@ -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 @@ namespace MvcSample.Web
|
|||
|
||||
context.Result = new ContentResult
|
||||
{
|
||||
ContentType = "text/plain",
|
||||
ContentType = new MediaTypeHeaderValue("text/plain"),
|
||||
Content = "Boom " + context.Exception.Message
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
private readonly MediaTypeHeaderValue DefaultContentType = new MediaTypeHeaderValue("text/plain")
|
||||
{
|
||||
Encoding = Encodings.UTF8EncodingWithoutBOM
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets or set the content representing the body of the response.
|
||||
/// </summary>
|
||||
public string Content { get; set; }
|
||||
|
||||
public Encoding ContentEncoding { get; set; }
|
||||
|
||||
public string ContentType { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="MediaTypeHeaderValue"/> representing the Content-Type header of the response.
|
||||
/// </summary>
|
||||
public MediaTypeHeaderValue ContentType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the HTTP status code.
|
||||
|
|
@ -26,17 +37,30 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
if (Content != null)
|
||||
{
|
||||
await response.WriteAsync(Content, contentTypeHeader.Encoding);
|
||||
await response.WriteAsync(Content, encoding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using System.Threading;
|
|||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="FileContentResult"/> instance with
|
||||
/// the provided <paramref name="fileContents"/>.
|
||||
/// the provided <paramref name="fileContents"/> and the
|
||||
/// provided <paramref name="contentType"/>.
|
||||
/// </summary>
|
||||
/// <param name="fileContents">The bytes that represent the file contents.</param>
|
||||
public FileContentResult([NotNull] byte[] fileContents)
|
||||
: base(contentType: null)
|
||||
/// <param name="contentType">The Content-Type header of the response.</param>
|
||||
public FileContentResult([NotNull] byte[] fileContents, [NotNull] string contentType)
|
||||
: this(fileContents, new MediaTypeHeaderValue(contentType))
|
||||
{
|
||||
FileContents = fileContents;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -35,7 +37,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// </summary>
|
||||
/// <param name="fileContents">The bytes that represent the file contents.</param>
|
||||
/// <param name="contentType">The Content-Type header of the response.</param>
|
||||
public FileContentResult([NotNull] byte[] fileContents, string contentType)
|
||||
public FileContentResult([NotNull] byte[] fileContents, [NotNull] MediaTypeHeaderValue contentType)
|
||||
: base(contentType)
|
||||
{
|
||||
FileContents = fileContents;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ using Microsoft.AspNet.Http;
|
|||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="FilePathResult"/> instance with
|
||||
/// the provided <paramref name="fileName"/>
|
||||
/// the provided <paramref name="fileName"/> and the
|
||||
/// provided <paramref name="contentType"/>.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The path to the file. The path must be an absolute
|
||||
/// path. Relative and virtual paths are not supported.</param>
|
||||
/// <param name="contentType">The Content-Type header of the response.</param>
|
||||
public FilePathResult([NotNull] string fileName)
|
||||
: base(contentType: null)
|
||||
public FilePathResult([NotNull] string fileName, [NotNull] string contentType)
|
||||
: this(fileName, new MediaTypeHeaderValue(contentType))
|
||||
{
|
||||
FileName = fileName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -46,7 +47,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// <param name="fileName">The path to the file. The path must be an absolute
|
||||
/// path. Relative and virtual paths are not supported.</param>
|
||||
/// <param name="contentType">The Content-Type header of the response.</param>
|
||||
public FilePathResult([NotNull] string fileName, string contentType)
|
||||
public FilePathResult([NotNull] string fileName, [NotNull] MediaTypeHeaderValue contentType)
|
||||
: base(contentType)
|
||||
{
|
||||
FileName = fileName;
|
||||
|
|
|
|||
|
|
@ -24,15 +24,25 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// the provided <paramref name="contentType"/>.
|
||||
/// </summary>
|
||||
/// <param name="contentType">The Content-Type header of the response.</param>
|
||||
protected FileResult(string contentType)
|
||||
protected FileResult([NotNull] string contentType)
|
||||
: this(new MediaTypeHeaderValue(contentType))
|
||||
{
|
||||
}
|
||||
|
||||
/// <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([NotNull] MediaTypeHeaderValue contentType)
|
||||
{
|
||||
ContentType = contentType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Content-Type header value that will be written to the response.
|
||||
/// Gets the <see cref="MediaTypeHeaderValue"/> representing the Content-Type header of the response.
|
||||
/// </summary>
|
||||
public string ContentType { get; set; }
|
||||
public MediaTypeHeaderValue ContentType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file name that will be used in the Content-Disposition header of the response.
|
||||
|
|
@ -47,11 +57,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
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))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using System.Threading;
|
|||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="FileStreamResult"/> instance with
|
||||
/// the provided <paramref name="fileStream"/>.
|
||||
/// the provided <paramref name="fileStream"/> and the
|
||||
/// provided <paramref name="contentType"/>.
|
||||
/// </summary>
|
||||
/// <param name="fileStream">The stream with the file.</param>
|
||||
public FileStreamResult([NotNull] Stream fileStream)
|
||||
: base(contentType: null)
|
||||
/// <param name="contentType">The Content-Type header of the response.</param>
|
||||
public FileStreamResult([NotNull] Stream fileStream, [NotNull] string contentType)
|
||||
: this(fileStream, new MediaTypeHeaderValue(contentType))
|
||||
{
|
||||
FileStream = fileStream;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -39,7 +41,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// </summary>
|
||||
/// <param name="fileStream">The stream with the file.</param>
|
||||
/// <param name="contentType">The Content-Type header of the response.</param>
|
||||
public FileStreamResult([NotNull] Stream fileStream, string contentType)
|
||||
public FileStreamResult([NotNull] Stream fileStream, [NotNull] MediaTypeHeaderValue contentType)
|
||||
: base(contentType)
|
||||
{
|
||||
FileStream = fileStream;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using Microsoft.AspNet.Mvc.Rendering;
|
|||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// <c>ActionContext.HttpContext.RequestServices</c> is used.</remarks>
|
||||
public IViewEngine ViewEngine { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="MediaTypeHeaderValue"/> representing the Content-Type header of the response.
|
||||
/// </summary>
|
||||
public MediaTypeHeaderValue ContentType { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task ExecuteResultAsync([NotNull] ActionContext context)
|
||||
{
|
||||
|
|
@ -74,7 +80,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
using (view as IDisposable)
|
||||
{
|
||||
await ViewExecutor.ExecuteAsync(view, context, ViewData, TempData, contentType: null);
|
||||
await ViewExecutor.ExecuteAsync(view, context, ViewData, TempData, ContentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously renders the specified <paramref name="view"/> to the response body.
|
||||
|
|
@ -23,21 +29,43 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// <param name="actionContext">The <see cref="ActionContext"/> for the current executing action.</param>
|
||||
/// <param name="viewData">The <see cref="ViewDataDictionary"/> for the view being rendered.</param>
|
||||
/// <param name="tempData">The <see cref="ITempDataDictionary"/> for the view being rendered.</param>
|
||||
/// <returns>A <see cref="Task"/> that represents the asychronous rendering.</returns>
|
||||
/// <returns>A <see cref="Task"/> that represents the asynchronous rendering.</returns>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
actionContext.HttpContext.Response.ContentType = contentType;
|
||||
var wrappedStream = new StreamWrapper(actionContext.HttpContext.Response.Body);
|
||||
var encoding = Encodings.UTF8EncodingWithoutBOM;
|
||||
response.ContentType = contentTypeHeader.ToString();
|
||||
|
||||
var wrappedStream = new StreamWrapper(response.Body);
|
||||
|
||||
using (var writer = new StreamWriter(wrappedStream, encoding, BufferSize, leaveOpen: true))
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using Microsoft.AspNet.Mvc.Rendering;
|
|||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// <c>ActionContext.HttpContext.RequestServices</c> is used.</remarks>
|
||||
public IViewEngine ViewEngine { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="MediaTypeHeaderValue"/> representing the Content-Type header of the response.
|
||||
/// </summary>
|
||||
public MediaTypeHeaderValue ContentType { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task ExecuteResultAsync([NotNull] ActionContext context)
|
||||
{
|
||||
|
|
@ -74,7 +80,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
using (view as IDisposable)
|
||||
{
|
||||
await ViewExecutor.ExecuteAsync(view, context, ViewData, TempData, contentType: null);
|
||||
await ViewExecutor.ExecuteAsync(view, context, ViewData, TempData, ContentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ using Microsoft.AspNet.Mvc.ModelBinding.Validation;
|
|||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
[NonAction]
|
||||
public virtual ContentResult Content(string content)
|
||||
{
|
||||
return Content(content, contentType: null);
|
||||
return Content(content, (MediaTypeHeaderValue)null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -356,11 +357,23 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// <returns>The created <see cref="ContentResult"/> object for the response.</returns>
|
||||
[NonAction]
|
||||
public virtual ContentResult Content(string content, string contentType, Encoding contentEncoding)
|
||||
{
|
||||
return Content(content, new MediaTypeHeaderValue(contentType) { Encoding = contentEncoding });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="ContentResult"/> object by specifying a <paramref name="content"/>
|
||||
/// string and a <paramref name="contentType"/>.
|
||||
/// </summary>
|
||||
/// <param name="content">The content to write to the response.</param>
|
||||
/// <param name="contentType">The content type (MIME type).</param>
|
||||
/// <returns>The created <see cref="ContentResult"/> object for the response.</returns>
|
||||
[NonAction]
|
||||
public virtual ContentResult Content(string content, MediaTypeHeaderValue contentType)
|
||||
{
|
||||
var result = new ContentResult
|
||||
{
|
||||
Content = content,
|
||||
ContentEncoding = contentEncoding,
|
||||
ContentType = contentType
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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 @@ namespace Microsoft.AspNet.Mvc
|
|||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
[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 @@ namespace Microsoft.AspNet.Mvc
|
|||
Assert.Equal("text/plain; charset=utf-7", httpContext.Response.ContentType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ContentResult_Response_NullContent_SetsContentTypeAndEncoding()
|
||||
public static TheoryData<MediaTypeHeaderValue, string, string, byte[]> ContentResultContentTypeData
|
||||
{
|
||||
get
|
||||
{
|
||||
return new TheoryData<MediaTypeHeaderValue, string, string, byte[]>
|
||||
{
|
||||
{
|
||||
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 }
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[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 = null,
|
||||
ContentType = "application/json",
|
||||
ContentEncoding = Encoding.UTF8
|
||||
Content = content,
|
||||
ContentType = contentType
|
||||
};
|
||||
var httpContext = GetHttpContext();
|
||||
var memoryStream = new MemoryStream();
|
||||
httpContext.Response.Body = memoryStream;
|
||||
var actionContext = GetActionContext(httpContext);
|
||||
|
||||
// Act
|
||||
await contentResult.ExecuteResultAsync(actionContext);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("application/json; charset=utf-8", httpContext.Response.ContentType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ContentResult_Response_BadContentType_ThrowsFormatException()
|
||||
{
|
||||
// Arrange
|
||||
var contentResult = new ContentResult
|
||||
{
|
||||
Content = "Test Content",
|
||||
ContentType = "some-type",
|
||||
ContentEncoding = null
|
||||
};
|
||||
var httpContext = GetHttpContext();
|
||||
var actionContext = GetActionContext(httpContext);
|
||||
|
||||
// Act
|
||||
var exception = await Assert.ThrowsAsync<FormatException>(
|
||||
async () => 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)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System.IO;
|
|||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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.Hosting;
|
|||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
nonDiskFileInfo.Setup(fi => fi.CreateReadStream()).Returns(sourceStream);
|
||||
var nonDiskFileProvider = new Mock<IFileProvider>();
|
||||
nonDiskFileProvider.Setup(fp => fp.GetFileInfo(It.IsAny<string>())).Returns(nonDiskFileInfo.Object);
|
||||
var filePathResult = new FilePathResult("/SampleEmbeddedFile.txt")
|
||||
var filePathResult = new FilePathResult("/SampleEmbeddedFile.txt", "text/plain")
|
||||
{
|
||||
FileProvider = nonDiskFileProvider.Object
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
var result = new EmptyFileResult("text/plain");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("text/plain", result.ContentType);
|
||||
Assert.Equal("text/plain", result.ContentType.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using System.Threading;
|
|||
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 @@ namespace Microsoft.AspNet.Mvc
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 @@ namespace Microsoft.AspNet.Mvc
|
|||
viewEngine.Verify();
|
||||
}
|
||||
|
||||
public static TheoryData<MediaTypeHeaderValue, string> PartialViewResultContentTypeData
|
||||
{
|
||||
get
|
||||
{
|
||||
return new TheoryData<MediaTypeHeaderValue, string>
|
||||
{
|
||||
{
|
||||
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<IViewEngine>();
|
||||
var view = Mock.Of<IView>();
|
||||
|
||||
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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 @@ namespace Microsoft.AspNet.Mvc
|
|||
// The buffer size of the StreamWriter used in ViewResult.
|
||||
private const int ViewResultStreamWriterBufferSize = 1024;
|
||||
|
||||
[Fact]
|
||||
public async Task ExecuteAsync_WritesOutputWithoutBOM()
|
||||
public static TheoryData<MediaTypeHeaderValue, string, byte[]> ViewExecutorSetsContentTypeAndEncodingData
|
||||
{
|
||||
get
|
||||
{
|
||||
return new TheoryData<MediaTypeHeaderValue, string, byte[]>
|
||||
{
|
||||
{
|
||||
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 expected = new byte[] { 97, 98, 99, 100 };
|
||||
|
||||
var view = new Mock<IView>();
|
||||
view.Setup(v => v.RenderAsync(It.IsAny<ViewContext>()))
|
||||
.Callback((ViewContext v) =>
|
||||
|
|
@ -44,33 +78,11 @@ namespace Microsoft.AspNet.Mvc
|
|||
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
|
||||
|
||||
// Act
|
||||
await ViewExecutor.ExecuteAsync(view.Object, actionContext, viewData, null, contentType: null);
|
||||
await ViewExecutor.ExecuteAsync(view.Object, actionContext, viewData, null, contentType);
|
||||
|
||||
// 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<IView>();
|
||||
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);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(contentType, context.Response.ContentType);
|
||||
Assert.Equal(expectedContentType, context.Response.ContentType);
|
||||
Assert.Equal(expectedContentData, memoryStream.ToArray());
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> ExecuteAsync_DoesNotWriteToResponse_OnceExceptionIsThrownData
|
||||
|
|
|
|||
|
|
@ -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 @@ namespace Microsoft.AspNet.Mvc
|
|||
viewEngine.Verify();
|
||||
}
|
||||
|
||||
public static TheoryData<MediaTypeHeaderValue, string> ViewResultContentTypeData
|
||||
{
|
||||
get
|
||||
{
|
||||
return new TheoryData<MediaTypeHeaderValue, string>
|
||||
{
|
||||
{
|
||||
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<IViewEngine>();
|
||||
var view = Mock.Of<IView>();
|
||||
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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -627,12 +627,12 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
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 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
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<Action<object>>(), It.IsAny<object>()),
|
||||
|
|
@ -980,7 +980,6 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
// Assert
|
||||
Assert.IsType<ContentResult>(actualContentResult);
|
||||
Assert.Equal("TestContent", actualContentResult.Content);
|
||||
Assert.Null(actualContentResult.ContentEncoding);
|
||||
Assert.Null(actualContentResult.ContentType);
|
||||
}
|
||||
|
||||
|
|
@ -996,8 +995,8 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
// Assert
|
||||
Assert.IsType<ContentResult>(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 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
// Assert
|
||||
Assert.IsType<ContentResult>(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]
|
||||
|
|
|
|||
|
|
@ -71,11 +71,13 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
}
|
||||
|
||||
[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 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
var contentResult = Assert.IsType<ContentResult>(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 @@ namespace Microsoft.AspNet.Mvc
|
|||
Assert.Equal(StatusCodes.Status201Created, createdResult.StatusCode);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("<html>CreatedBody</html>", "text/html", "Created.html")]
|
||||
[InlineData("<html>CreatedBody</html>", null, null)]
|
||||
public void ControllerFileContent_InvokedInUnitTests(string content, string contentType, string fileName)
|
||||
[Fact]
|
||||
public void ControllerFileContent_InvokedInUnitTests()
|
||||
{
|
||||
// Arrange
|
||||
var content = "<html>CreatedBody</html>";
|
||||
var contentType = "text/html";
|
||||
var fileName = "Created.html";
|
||||
var controller = new TestabilityController();
|
||||
|
||||
// Act
|
||||
|
|
@ -125,7 +128,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
Assert.NotNull(result);
|
||||
|
||||
var fileContentResult = Assert.IsType<FileContentResult>(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 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("<html>CreatedBody</html>", "text/html", "Created.html")]
|
||||
[InlineData("<html>CreatedBody</html>", null, null)]
|
||||
public void ControllerFileStream_InvokedInUnitTests(string content, string contentType, string fileName)
|
||||
[Fact]
|
||||
public void ControllerFileStream_InvokedInUnitTests()
|
||||
{
|
||||
// Arrange
|
||||
var content = "<html>CreatedBody</html>";
|
||||
var contentType = "text/html";
|
||||
var fileName = "Created.html";
|
||||
var mockHttpContext = new Mock<DefaultHttpContext>();
|
||||
mockHttpContext.Setup(x => x.Response.OnResponseCompleted(It.IsAny<Action<object>>(), It.IsAny<object>()));
|
||||
var controller = new TestabilityController()
|
||||
|
|
@ -158,7 +162,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
Assert.NotNull(result);
|
||||
|
||||
var fileStreamResult = Assert.IsType<FileStreamResult>(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 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> 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)
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
FilePathResultTestFile contents ASCII encoded
|
||||
|
|
@ -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 @@ namespace FiltersWebSite
|
|||
context.Result = new ContentResult()
|
||||
{
|
||||
Content = "4",
|
||||
ContentType = "text/plain"
|
||||
ContentType = new MediaTypeHeaderValue("text/plain")
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 @@ namespace FiltersWebSite
|
|||
context.Result = new ContentResult
|
||||
{
|
||||
Content = "The Action was never executed",
|
||||
ContentType = "text/plain"
|
||||
ContentType = new MediaTypeHeaderValue("text/plain")
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 @@ namespace FiltersWebSite
|
|||
return new ContentResult()
|
||||
{
|
||||
Content = content,
|
||||
ContentType = "text/plain",
|
||||
ContentType = new MediaTypeHeaderValue("text/plain"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue