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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using Microsoft.AspNet.Mvc;
|
using Microsoft.AspNet.Mvc;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace MvcSample.Web
|
namespace MvcSample.Web
|
||||||
{
|
{
|
||||||
|
|
@ -15,7 +16,7 @@ namespace MvcSample.Web
|
||||||
|
|
||||||
context.Result = new ContentResult
|
context.Result = new ContentResult
|
||||||
{
|
{
|
||||||
ContentType = "text/plain",
|
ContentType = new MediaTypeHeaderValue("text/plain"),
|
||||||
Content = "Boom " + context.Exception.Message
|
Content = "Boom " + context.Exception.Message
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// 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.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
|
|
@ -11,11 +13,20 @@ namespace Microsoft.AspNet.Mvc
|
||||||
{
|
{
|
||||||
public class ContentResult : ActionResult
|
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 string Content { get; set; }
|
||||||
|
|
||||||
public Encoding ContentEncoding { get; set; }
|
/// <summary>
|
||||||
|
/// Gets or sets the <see cref="MediaTypeHeaderValue"/> representing the Content-Type header of the response.
|
||||||
public string ContentType { get; set; }
|
/// </summary>
|
||||||
|
public MediaTypeHeaderValue ContentType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the HTTP status code.
|
/// Gets or sets the HTTP status code.
|
||||||
|
|
@ -26,17 +37,30 @@ namespace Microsoft.AspNet.Mvc
|
||||||
{
|
{
|
||||||
var response = context.HttpContext.Response;
|
var response = context.HttpContext.Response;
|
||||||
|
|
||||||
MediaTypeHeaderValue contentTypeHeader;
|
var contentTypeHeader = ContentType;
|
||||||
if (string.IsNullOrEmpty(ContentType))
|
Encoding encoding;
|
||||||
|
if (contentTypeHeader == null)
|
||||||
{
|
{
|
||||||
contentTypeHeader = new MediaTypeHeaderValue("text/plain");
|
contentTypeHeader = DefaultContentType;
|
||||||
|
encoding = Encodings.UTF8EncodingWithoutBOM;
|
||||||
}
|
}
|
||||||
else
|
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();
|
response.ContentType = contentTypeHeader.ToString();
|
||||||
|
|
||||||
if (StatusCode != null)
|
if (StatusCode != null)
|
||||||
|
|
@ -46,7 +70,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
if (Content != null)
|
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 System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.Framework.Internal;
|
using Microsoft.Framework.Internal;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc
|
namespace Microsoft.AspNet.Mvc
|
||||||
{
|
{
|
||||||
|
|
@ -19,13 +20,14 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new <see cref="FileContentResult"/> instance with
|
/// 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>
|
/// </summary>
|
||||||
/// <param name="fileContents">The bytes that represent the file contents.</param>
|
/// <param name="fileContents">The bytes that represent the file contents.</param>
|
||||||
public FileContentResult([NotNull] byte[] fileContents)
|
/// <param name="contentType">The Content-Type header of the response.</param>
|
||||||
: base(contentType: null)
|
public FileContentResult([NotNull] byte[] fileContents, [NotNull] string contentType)
|
||||||
|
: this(fileContents, new MediaTypeHeaderValue(contentType))
|
||||||
{
|
{
|
||||||
FileContents = fileContents;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -35,7 +37,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fileContents">The bytes that represent the file contents.</param>
|
/// <param name="fileContents">The bytes that represent the file contents.</param>
|
||||||
/// <param name="contentType">The Content-Type header of the response.</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)
|
: base(contentType)
|
||||||
{
|
{
|
||||||
FileContents = fileContents;
|
FileContents = fileContents;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Mvc.Core;
|
using Microsoft.AspNet.Mvc.Core;
|
||||||
using Microsoft.Framework.DependencyInjection;
|
using Microsoft.Framework.DependencyInjection;
|
||||||
using Microsoft.Framework.Internal;
|
using Microsoft.Framework.Internal;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc
|
namespace Microsoft.AspNet.Mvc
|
||||||
{
|
{
|
||||||
|
|
@ -27,15 +28,15 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new <see cref="FilePathResult"/> instance with
|
/// 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>
|
/// </summary>
|
||||||
/// <param name="fileName">The path to the file. The path must be an absolute
|
/// <param name="fileName">The path to the file. The path must be an absolute
|
||||||
/// path. Relative and virtual paths are not supported.</param>
|
/// path. Relative and virtual paths are not supported.</param>
|
||||||
/// <param name="contentType">The Content-Type header of the response.</param>
|
/// <param name="contentType">The Content-Type header of the response.</param>
|
||||||
public FilePathResult([NotNull] string fileName)
|
public FilePathResult([NotNull] string fileName, [NotNull] string contentType)
|
||||||
: base(contentType: null)
|
: this(fileName, new MediaTypeHeaderValue(contentType))
|
||||||
{
|
{
|
||||||
FileName = fileName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -46,7 +47,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// <param name="fileName">The path to the file. The path must be an absolute
|
/// <param name="fileName">The path to the file. The path must be an absolute
|
||||||
/// path. Relative and virtual paths are not supported.</param>
|
/// path. Relative and virtual paths are not supported.</param>
|
||||||
/// <param name="contentType">The Content-Type header of the response.</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)
|
: base(contentType)
|
||||||
{
|
{
|
||||||
FileName = fileName;
|
FileName = fileName;
|
||||||
|
|
|
||||||
|
|
@ -24,15 +24,25 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// the provided <paramref name="contentType"/>.
|
/// the provided <paramref name="contentType"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="contentType">The Content-Type header of the response.</param>
|
/// <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;
|
ContentType = contentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <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>
|
/// </summary>
|
||||||
public string ContentType { get; set; }
|
public MediaTypeHeaderValue ContentType { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the file name that will be used in the Content-Disposition header of the response.
|
/// 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)
|
public override Task ExecuteResultAsync([NotNull] ActionContext context)
|
||||||
{
|
{
|
||||||
var response = context.HttpContext.Response;
|
var response = context.HttpContext.Response;
|
||||||
|
response.ContentType = ContentType.ToString();
|
||||||
if (ContentType != null)
|
|
||||||
{
|
|
||||||
response.ContentType = ContentType;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(FileDownloadName))
|
if (!string.IsNullOrEmpty(FileDownloadName))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.Framework.Internal;
|
using Microsoft.Framework.Internal;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc
|
namespace Microsoft.AspNet.Mvc
|
||||||
{
|
{
|
||||||
|
|
@ -23,13 +24,14 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new <see cref="FileStreamResult"/> instance with
|
/// 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>
|
/// </summary>
|
||||||
/// <param name="fileStream">The stream with the file.</param>
|
/// <param name="fileStream">The stream with the file.</param>
|
||||||
public FileStreamResult([NotNull] Stream fileStream)
|
/// <param name="contentType">The Content-Type header of the response.</param>
|
||||||
: base(contentType: null)
|
public FileStreamResult([NotNull] Stream fileStream, [NotNull] string contentType)
|
||||||
|
: this(fileStream, new MediaTypeHeaderValue(contentType))
|
||||||
{
|
{
|
||||||
FileStream = fileStream;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -39,7 +41,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fileStream">The stream with the file.</param>
|
/// <param name="fileStream">The stream with the file.</param>
|
||||||
/// <param name="contentType">The Content-Type header of the response.</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)
|
: base(contentType)
|
||||||
{
|
{
|
||||||
FileStream = fileStream;
|
FileStream = fileStream;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using Microsoft.AspNet.Mvc.Rendering;
|
||||||
using Microsoft.Framework.DependencyInjection;
|
using Microsoft.Framework.DependencyInjection;
|
||||||
using Microsoft.Framework.Internal;
|
using Microsoft.Framework.Internal;
|
||||||
using Microsoft.Framework.Logging;
|
using Microsoft.Framework.Logging;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc
|
namespace Microsoft.AspNet.Mvc
|
||||||
{
|
{
|
||||||
|
|
@ -45,6 +46,11 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// <c>ActionContext.HttpContext.RequestServices</c> is used.</remarks>
|
/// <c>ActionContext.HttpContext.RequestServices</c> is used.</remarks>
|
||||||
public IViewEngine ViewEngine { get; set; }
|
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 />
|
/// <inheritdoc />
|
||||||
public override async Task ExecuteResultAsync([NotNull] ActionContext context)
|
public override async Task ExecuteResultAsync([NotNull] ActionContext context)
|
||||||
{
|
{
|
||||||
|
|
@ -74,7 +80,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
using (view as IDisposable)
|
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.
|
// 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.
|
// 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.IO;
|
||||||
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Mvc.Rendering;
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
using Microsoft.Framework.Internal;
|
using Microsoft.Framework.Internal;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc
|
namespace Microsoft.AspNet.Mvc
|
||||||
{
|
{
|
||||||
|
|
@ -14,7 +17,10 @@ namespace Microsoft.AspNet.Mvc
|
||||||
public static class ViewExecutor
|
public static class ViewExecutor
|
||||||
{
|
{
|
||||||
private const int BufferSize = 1024;
|
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>
|
/// <summary>
|
||||||
/// Asynchronously renders the specified <paramref name="view"/> to the response body.
|
/// 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="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="viewData">The <see cref="ViewDataDictionary"/> for the view being rendered.</param>
|
||||||
/// <param name="tempData">The <see cref="ITempDataDictionary"/> 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,
|
public static async Task ExecuteAsync([NotNull] IView view,
|
||||||
[NotNull] ActionContext actionContext,
|
[NotNull] ActionContext actionContext,
|
||||||
[NotNull] ViewDataDictionary viewData,
|
[NotNull] ViewDataDictionary viewData,
|
||||||
[NotNull] ITempDataDictionary tempData,
|
[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;
|
response.ContentType = contentTypeHeader.ToString();
|
||||||
var wrappedStream = new StreamWrapper(actionContext.HttpContext.Response.Body);
|
|
||||||
var encoding = Encodings.UTF8EncodingWithoutBOM;
|
var wrappedStream = new StreamWrapper(response.Body);
|
||||||
|
|
||||||
using (var writer = new StreamWriter(wrappedStream, encoding, BufferSize, leaveOpen: true))
|
using (var writer = new StreamWriter(wrappedStream, encoding, BufferSize, leaveOpen: true))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using Microsoft.AspNet.Mvc.Rendering;
|
||||||
using Microsoft.Framework.DependencyInjection;
|
using Microsoft.Framework.DependencyInjection;
|
||||||
using Microsoft.Framework.Internal;
|
using Microsoft.Framework.Internal;
|
||||||
using Microsoft.Framework.Logging;
|
using Microsoft.Framework.Logging;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc
|
namespace Microsoft.AspNet.Mvc
|
||||||
{
|
{
|
||||||
|
|
@ -45,6 +46,11 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// <c>ActionContext.HttpContext.RequestServices</c> is used.</remarks>
|
/// <c>ActionContext.HttpContext.RequestServices</c> is used.</remarks>
|
||||||
public IViewEngine ViewEngine { get; set; }
|
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 />
|
/// <inheritdoc />
|
||||||
public override async Task ExecuteResultAsync([NotNull] ActionContext context)
|
public override async Task ExecuteResultAsync([NotNull] ActionContext context)
|
||||||
{
|
{
|
||||||
|
|
@ -74,7 +80,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
using (view as IDisposable)
|
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.Mvc.Rendering;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
using Microsoft.Framework.Internal;
|
using Microsoft.Framework.Internal;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc
|
namespace Microsoft.AspNet.Mvc
|
||||||
{
|
{
|
||||||
|
|
@ -330,7 +331,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
[NonAction]
|
[NonAction]
|
||||||
public virtual ContentResult Content(string content)
|
public virtual ContentResult Content(string content)
|
||||||
{
|
{
|
||||||
return Content(content, contentType: null);
|
return Content(content, (MediaTypeHeaderValue)null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -356,11 +357,23 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// <returns>The created <see cref="ContentResult"/> object for the response.</returns>
|
/// <returns>The created <see cref="ContentResult"/> object for the response.</returns>
|
||||||
[NonAction]
|
[NonAction]
|
||||||
public virtual ContentResult Content(string content, string contentType, Encoding contentEncoding)
|
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
|
var result = new ContentResult
|
||||||
{
|
{
|
||||||
Content = content,
|
Content = content,
|
||||||
ContentEncoding = contentEncoding,
|
|
||||||
ContentType = contentType
|
ContentType = contentType
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// 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.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -20,8 +21,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
var contentResult = new ContentResult
|
var contentResult = new ContentResult
|
||||||
{
|
{
|
||||||
Content = "Test Content",
|
Content = "Test Content",
|
||||||
ContentType = "application/json",
|
ContentType = new MediaTypeHeaderValue("application/json")
|
||||||
ContentEncoding = null
|
|
||||||
};
|
};
|
||||||
var httpContext = GetHttpContext();
|
var httpContext = GetHttpContext();
|
||||||
var actionContext = GetActionContext(httpContext);
|
var actionContext = GetActionContext(httpContext);
|
||||||
|
|
@ -40,8 +40,10 @@ namespace Microsoft.AspNet.Mvc
|
||||||
var contentResult = new ContentResult
|
var contentResult = new ContentResult
|
||||||
{
|
{
|
||||||
Content = "Test Content",
|
Content = "Test Content",
|
||||||
ContentType = "text/plain",
|
ContentType = new MediaTypeHeaderValue("text/plain")
|
||||||
ContentEncoding = Encoding.ASCII
|
{
|
||||||
|
Encoding = Encoding.ASCII
|
||||||
|
}
|
||||||
};
|
};
|
||||||
var httpContext = GetHttpContext();
|
var httpContext = GetHttpContext();
|
||||||
var actionContext = GetActionContext(httpContext);
|
var actionContext = GetActionContext(httpContext);
|
||||||
|
|
@ -54,14 +56,16 @@ namespace Microsoft.AspNet.Mvc
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ContentResult_Response_NullContentType_SetsEncodingAndDefaultContentType()
|
public async Task ContentResult_Response_NullContent_SetsContentTypeAndEncoding()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var contentResult = new ContentResult
|
var contentResult = new ContentResult
|
||||||
{
|
{
|
||||||
Content = "Test Content",
|
Content = null,
|
||||||
ContentType = null,
|
ContentType = new MediaTypeHeaderValue("text/plain")
|
||||||
ContentEncoding = Encoding.UTF7
|
{
|
||||||
|
Encoding = Encoding.UTF7
|
||||||
|
}
|
||||||
};
|
};
|
||||||
var httpContext = GetHttpContext();
|
var httpContext = GetHttpContext();
|
||||||
var actionContext = GetActionContext(httpContext);
|
var actionContext = GetActionContext(httpContext);
|
||||||
|
|
@ -73,45 +77,65 @@ namespace Microsoft.AspNet.Mvc
|
||||||
Assert.Equal("text/plain; charset=utf-7", httpContext.Response.ContentType);
|
Assert.Equal("text/plain; charset=utf-7", httpContext.Response.ContentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
public static TheoryData<MediaTypeHeaderValue, string, string, byte[]> ContentResultContentTypeData
|
||||||
public async Task ContentResult_Response_NullContent_SetsContentTypeAndEncoding()
|
{
|
||||||
|
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
|
// Arrange
|
||||||
var contentResult = new ContentResult
|
var contentResult = new ContentResult
|
||||||
{
|
{
|
||||||
Content = null,
|
Content = content,
|
||||||
ContentType = "application/json",
|
ContentType = contentType
|
||||||
ContentEncoding = Encoding.UTF8
|
|
||||||
};
|
};
|
||||||
var httpContext = GetHttpContext();
|
var httpContext = GetHttpContext();
|
||||||
|
var memoryStream = new MemoryStream();
|
||||||
|
httpContext.Response.Body = memoryStream;
|
||||||
var actionContext = GetActionContext(httpContext);
|
var actionContext = GetActionContext(httpContext);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await contentResult.ExecuteResultAsync(actionContext);
|
await contentResult.ExecuteResultAsync(actionContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal("application/json; charset=utf-8", httpContext.Response.ContentType);
|
Assert.Equal(expectedContentType, httpContext.Response.ContentType);
|
||||||
}
|
Assert.Equal(expectedContentData, memoryStream.ToArray());
|
||||||
|
|
||||||
[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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ActionContext GetActionContext(HttpContext httpContext)
|
private static ActionContext GetActionContext(HttpContext httpContext)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc
|
namespace Microsoft.AspNet.Mvc
|
||||||
|
|
@ -45,5 +46,29 @@ namespace Microsoft.AspNet.Mvc
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(buffer, outStream.ToArray());
|
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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.FileProviders;
|
using Microsoft.AspNet.FileProviders;
|
||||||
|
|
@ -9,9 +10,9 @@ using Microsoft.AspNet.Hosting;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
using Microsoft.Framework.DependencyInjection;
|
using Microsoft.Framework.DependencyInjection;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc
|
namespace Microsoft.AspNet.Mvc
|
||||||
{
|
{
|
||||||
|
|
@ -111,6 +112,36 @@ namespace Microsoft.AspNet.Mvc
|
||||||
sendFileMock.Verify();
|
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]
|
[Fact]
|
||||||
public async Task ExecuteResultAsync_WorksWithAbsolutePaths_UsingBackSlash()
|
public async Task ExecuteResultAsync_WorksWithAbsolutePaths_UsingBackSlash()
|
||||||
{
|
{
|
||||||
|
|
@ -186,7 +217,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
nonDiskFileInfo.Setup(fi => fi.CreateReadStream()).Returns(sourceStream);
|
nonDiskFileInfo.Setup(fi => fi.CreateReadStream()).Returns(sourceStream);
|
||||||
var nonDiskFileProvider = new Mock<IFileProvider>();
|
var nonDiskFileProvider = new Mock<IFileProvider>();
|
||||||
nonDiskFileProvider.Setup(fp => fp.GetFileInfo(It.IsAny<string>())).Returns(nonDiskFileInfo.Object);
|
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
|
FileProvider = nonDiskFileProvider.Object
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
var result = new EmptyFileResult("text/plain");
|
var result = new EmptyFileResult("text/plain");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal("text/plain", result.ContentType);
|
Assert.Equal("text/plain", result.ContentType.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -87,5 +88,34 @@ namespace Microsoft.AspNet.Mvc
|
||||||
var outBytes = outStream.ToArray();
|
var outBytes = outStream.ToArray();
|
||||||
Assert.True(originalBytes.SequenceEqual(outBytes));
|
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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Mvc.Rendering;
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
using Microsoft.Framework.Logging;
|
using Microsoft.Framework.Logging;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -69,6 +71,58 @@ namespace Microsoft.AspNet.Mvc
|
||||||
viewEngine.Verify();
|
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]
|
[Fact]
|
||||||
public async Task ExecuteResultAsync_UsesActionDescriptorName_IfViewNameIsNull()
|
public async Task ExecuteResultAsync_UsesActionDescriptorName_IfViewNameIsNull()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,13 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNet.Mvc.Rendering;
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -19,12 +21,44 @@ namespace Microsoft.AspNet.Mvc
|
||||||
// The buffer size of the StreamWriter used in ViewResult.
|
// The buffer size of the StreamWriter used in ViewResult.
|
||||||
private const int ViewResultStreamWriterBufferSize = 1024;
|
private const int ViewResultStreamWriterBufferSize = 1024;
|
||||||
|
|
||||||
[Fact]
|
public static TheoryData<MediaTypeHeaderValue, string, byte[]> ViewExecutorSetsContentTypeAndEncodingData
|
||||||
public async Task ExecuteAsync_WritesOutputWithoutBOM()
|
{
|
||||||
|
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
|
// Arrange
|
||||||
var expected = new byte[] { 97, 98, 99, 100 };
|
|
||||||
|
|
||||||
var view = new Mock<IView>();
|
var view = new Mock<IView>();
|
||||||
view.Setup(v => v.RenderAsync(It.IsAny<ViewContext>()))
|
view.Setup(v => v.RenderAsync(It.IsAny<ViewContext>()))
|
||||||
.Callback((ViewContext v) =>
|
.Callback((ViewContext v) =>
|
||||||
|
|
@ -44,33 +78,11 @@ namespace Microsoft.AspNet.Mvc
|
||||||
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
|
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await ViewExecutor.ExecuteAsync(view.Object, actionContext, viewData, null, contentType: null);
|
await ViewExecutor.ExecuteAsync(view.Object, actionContext, viewData, null, contentType);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(expected, memoryStream.ToArray());
|
Assert.Equal(expectedContentType, context.Response.ContentType);
|
||||||
Assert.Equal("text/html; charset=utf-8", context.Response.ContentType);
|
Assert.Equal(expectedContentData, memoryStream.ToArray());
|
||||||
}
|
|
||||||
|
|
||||||
[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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<object[]> ExecuteAsync_DoesNotWriteToResponse_OnceExceptionIsThrownData
|
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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Mvc.Rendering;
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
using Microsoft.Framework.Logging;
|
using Microsoft.Framework.Logging;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -70,6 +72,69 @@ namespace Microsoft.AspNet.Mvc
|
||||||
viewEngine.Verify();
|
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]
|
[Fact]
|
||||||
public async Task ExecuteResultAsync_UsesActionDescriptorName_IfViewNameIsNull()
|
public async Task ExecuteResultAsync_UsesActionDescriptorName_IfViewNameIsNull()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -627,12 +627,12 @@ namespace Microsoft.AspNet.Mvc.Test
|
||||||
var fileContents = new byte[0];
|
var fileContents = new byte[0];
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = controller.File(fileContents, "someContentType");
|
var result = controller.File(fileContents, "application/pdf");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(result);
|
Assert.NotNull(result);
|
||||||
Assert.Same(fileContents, result.FileContents);
|
Assert.Same(fileContents, result.FileContents);
|
||||||
Assert.Equal("someContentType", result.ContentType);
|
Assert.Equal("application/pdf", result.ContentType.ToString());
|
||||||
Assert.Equal(string.Empty, result.FileDownloadName);
|
Assert.Equal(string.Empty, result.FileDownloadName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -644,12 +644,12 @@ namespace Microsoft.AspNet.Mvc.Test
|
||||||
var fileContents = new byte[0];
|
var fileContents = new byte[0];
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = controller.File(fileContents, "someContentType", "someDownloadName");
|
var result = controller.File(fileContents, "application/pdf", "someDownloadName");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(result);
|
Assert.NotNull(result);
|
||||||
Assert.Same(fileContents, result.FileContents);
|
Assert.Same(fileContents, result.FileContents);
|
||||||
Assert.Equal("someContentType", result.ContentType);
|
Assert.Equal("application/pdf", result.ContentType.ToString());
|
||||||
Assert.Equal("someDownloadName", result.FileDownloadName);
|
Assert.Equal("someDownloadName", result.FileDownloadName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -661,12 +661,12 @@ namespace Microsoft.AspNet.Mvc.Test
|
||||||
var path = Path.GetFullPath("somepath");
|
var path = Path.GetFullPath("somepath");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = controller.File(path, "someContentType");
|
var result = controller.File(path, "application/pdf");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(result);
|
Assert.NotNull(result);
|
||||||
Assert.Equal(path, result.FileName);
|
Assert.Equal(path, result.FileName);
|
||||||
Assert.Equal("someContentType", result.ContentType);
|
Assert.Equal("application/pdf", result.ContentType.ToString());
|
||||||
Assert.Equal(string.Empty, result.FileDownloadName);
|
Assert.Equal(string.Empty, result.FileDownloadName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -678,12 +678,12 @@ namespace Microsoft.AspNet.Mvc.Test
|
||||||
var path = Path.GetFullPath("somepath");
|
var path = Path.GetFullPath("somepath");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = controller.File(path, "someContentType", "someDownloadName");
|
var result = controller.File(path, "application/pdf", "someDownloadName");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(result);
|
Assert.NotNull(result);
|
||||||
Assert.Equal(path, result.FileName);
|
Assert.Equal(path, result.FileName);
|
||||||
Assert.Equal("someContentType", result.ContentType);
|
Assert.Equal("application/pdf", result.ContentType.ToString());
|
||||||
Assert.Equal("someDownloadName", result.FileDownloadName);
|
Assert.Equal("someDownloadName", result.FileDownloadName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -700,12 +700,12 @@ namespace Microsoft.AspNet.Mvc.Test
|
||||||
var fileStream = Stream.Null;
|
var fileStream = Stream.Null;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = controller.File(fileStream, "someContentType");
|
var result = controller.File(fileStream, "application/pdf");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(result);
|
Assert.NotNull(result);
|
||||||
Assert.Same(fileStream, result.FileStream);
|
Assert.Same(fileStream, result.FileStream);
|
||||||
Assert.Equal("someContentType", result.ContentType);
|
Assert.Equal("application/pdf", result.ContentType.ToString());
|
||||||
Assert.Equal(string.Empty, result.FileDownloadName);
|
Assert.Equal(string.Empty, result.FileDownloadName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -723,12 +723,12 @@ namespace Microsoft.AspNet.Mvc.Test
|
||||||
var fileStream = Stream.Null;
|
var fileStream = Stream.Null;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = controller.File(fileStream, "someContentType", "someDownloadName");
|
var result = controller.File(fileStream, "application/pdf", "someDownloadName");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(result);
|
Assert.NotNull(result);
|
||||||
Assert.Same(fileStream, result.FileStream);
|
Assert.Same(fileStream, result.FileStream);
|
||||||
Assert.Equal("someContentType", result.ContentType);
|
Assert.Equal("application/pdf", result.ContentType.ToString());
|
||||||
Assert.Equal("someDownloadName", result.FileDownloadName);
|
Assert.Equal("someDownloadName", result.FileDownloadName);
|
||||||
mockHttpContext.Verify(
|
mockHttpContext.Verify(
|
||||||
x => x.Response.OnResponseCompleted(It.IsAny<Action<object>>(), It.IsAny<object>()),
|
x => x.Response.OnResponseCompleted(It.IsAny<Action<object>>(), It.IsAny<object>()),
|
||||||
|
|
@ -980,7 +980,6 @@ namespace Microsoft.AspNet.Mvc.Test
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsType<ContentResult>(actualContentResult);
|
Assert.IsType<ContentResult>(actualContentResult);
|
||||||
Assert.Equal("TestContent", actualContentResult.Content);
|
Assert.Equal("TestContent", actualContentResult.Content);
|
||||||
Assert.Null(actualContentResult.ContentEncoding);
|
|
||||||
Assert.Null(actualContentResult.ContentType);
|
Assert.Null(actualContentResult.ContentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -996,8 +995,8 @@ namespace Microsoft.AspNet.Mvc.Test
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsType<ContentResult>(actualContentResult);
|
Assert.IsType<ContentResult>(actualContentResult);
|
||||||
Assert.Equal("TestContent", actualContentResult.Content);
|
Assert.Equal("TestContent", actualContentResult.Content);
|
||||||
Assert.Null(actualContentResult.ContentEncoding);
|
Assert.Null(actualContentResult.ContentType.Encoding);
|
||||||
Assert.Equal("text/plain", actualContentResult.ContentType);
|
Assert.Equal("text/plain", actualContentResult.ContentType.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -1012,8 +1011,8 @@ namespace Microsoft.AspNet.Mvc.Test
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsType<ContentResult>(actualContentResult);
|
Assert.IsType<ContentResult>(actualContentResult);
|
||||||
Assert.Equal("TestContent", actualContentResult.Content);
|
Assert.Equal("TestContent", actualContentResult.Content);
|
||||||
Assert.Same(Encoding.UTF8, actualContentResult.ContentEncoding);
|
Assert.Same(Encoding.UTF8, actualContentResult.ContentType.Encoding);
|
||||||
Assert.Equal("text/plain", actualContentResult.ContentType);
|
Assert.Equal("text/plain; charset=utf-8", actualContentResult.ContentType.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
|
|
@ -71,11 +71,13 @@ namespace Microsoft.AspNet.Mvc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Fact]
|
||||||
[MemberData(nameof(TestabilityContentTestData))]
|
public void ControllerContent_InvokedInUnitTests()
|
||||||
public void ControllerContent_InvokedInUnitTests(string content, string contentType, Encoding encoding)
|
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
|
var content = "Content_1";
|
||||||
|
var contentType = "text/asp";
|
||||||
|
var encoding = Encoding.ASCII;
|
||||||
var controller = new TestabilityController();
|
var controller = new TestabilityController();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -86,8 +88,8 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
var contentResult = Assert.IsType<ContentResult>(result);
|
var contentResult = Assert.IsType<ContentResult>(result);
|
||||||
Assert.Equal(content, contentResult.Content);
|
Assert.Equal(content, contentResult.Content);
|
||||||
Assert.Equal(contentType, contentResult.ContentType);
|
Assert.Equal("text/asp; charset=us-ascii", contentResult.ContentType.ToString());
|
||||||
Assert.Equal(encoding, contentResult.ContentEncoding);
|
Assert.Equal(encoding, contentResult.ContentType.Encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -110,12 +112,13 @@ namespace Microsoft.AspNet.Mvc
|
||||||
Assert.Equal(StatusCodes.Status201Created, createdResult.StatusCode);
|
Assert.Equal(StatusCodes.Status201Created, createdResult.StatusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Fact]
|
||||||
[InlineData("<html>CreatedBody</html>", "text/html", "Created.html")]
|
public void ControllerFileContent_InvokedInUnitTests()
|
||||||
[InlineData("<html>CreatedBody</html>", null, null)]
|
|
||||||
public void ControllerFileContent_InvokedInUnitTests(string content, string contentType, string fileName)
|
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
|
var content = "<html>CreatedBody</html>";
|
||||||
|
var contentType = "text/html";
|
||||||
|
var fileName = "Created.html";
|
||||||
var controller = new TestabilityController();
|
var controller = new TestabilityController();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -125,7 +128,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
Assert.NotNull(result);
|
Assert.NotNull(result);
|
||||||
|
|
||||||
var fileContentResult = Assert.IsType<FileContentResult>(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);
|
Assert.Equal(fileName ?? string.Empty, fileContentResult.FileDownloadName);
|
||||||
|
|
||||||
if (content == null)
|
if (content == null)
|
||||||
|
|
@ -138,12 +141,13 @@ namespace Microsoft.AspNet.Mvc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Fact]
|
||||||
[InlineData("<html>CreatedBody</html>", "text/html", "Created.html")]
|
public void ControllerFileStream_InvokedInUnitTests()
|
||||||
[InlineData("<html>CreatedBody</html>", null, null)]
|
|
||||||
public void ControllerFileStream_InvokedInUnitTests(string content, string contentType, string fileName)
|
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
|
var content = "<html>CreatedBody</html>";
|
||||||
|
var contentType = "text/html";
|
||||||
|
var fileName = "Created.html";
|
||||||
var mockHttpContext = new Mock<DefaultHttpContext>();
|
var mockHttpContext = new Mock<DefaultHttpContext>();
|
||||||
mockHttpContext.Setup(x => x.Response.OnResponseCompleted(It.IsAny<Action<object>>(), It.IsAny<object>()));
|
mockHttpContext.Setup(x => x.Response.OnResponseCompleted(It.IsAny<Action<object>>(), It.IsAny<object>()));
|
||||||
var controller = new TestabilityController()
|
var controller = new TestabilityController()
|
||||||
|
|
@ -158,7 +162,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
Assert.NotNull(result);
|
Assert.NotNull(result);
|
||||||
|
|
||||||
var fileStreamResult = Assert.IsType<FileStreamResult>(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);
|
Assert.Equal(fileName ?? string.Empty, fileStreamResult.FileDownloadName);
|
||||||
|
|
||||||
if (content == null)
|
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
|
private class TestabilityController : Controller
|
||||||
{
|
{
|
||||||
public IActionResult View_Action(string viewName, object data)
|
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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using Microsoft.AspNet.Mvc;
|
using Microsoft.AspNet.Mvc;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace FiltersWebSite
|
namespace FiltersWebSite
|
||||||
{
|
{
|
||||||
|
|
@ -12,7 +13,7 @@ namespace FiltersWebSite
|
||||||
context.Result = new ContentResult()
|
context.Result = new ContentResult()
|
||||||
{
|
{
|
||||||
Content = "4",
|
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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using Microsoft.AspNet.Mvc;
|
using Microsoft.AspNet.Mvc;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace FiltersWebSite
|
namespace FiltersWebSite
|
||||||
{
|
{
|
||||||
|
|
@ -12,7 +13,7 @@ namespace FiltersWebSite
|
||||||
context.Result = new ContentResult
|
context.Result = new ContentResult
|
||||||
{
|
{
|
||||||
Content = "The Action was never executed",
|
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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using Microsoft.AspNet.Mvc;
|
using Microsoft.AspNet.Mvc;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
namespace FiltersWebSite
|
namespace FiltersWebSite
|
||||||
{
|
{
|
||||||
|
|
@ -20,7 +21,7 @@ namespace FiltersWebSite
|
||||||
return new ContentResult()
|
return new ContentResult()
|
||||||
{
|
{
|
||||||
Content = content,
|
Content = content,
|
||||||
ContentType = "text/plain",
|
ContentType = new MediaTypeHeaderValue("text/plain"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue