[Fixes #2715] Removed formatter dependency from JsonResult and JsonViewComponentResult
This commit is contained in:
parent
d2908e7b7b
commit
e2787b3b84
|
|
@ -1,13 +1,10 @@
|
||||||
// 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.Collections.Generic;
|
using System.Text;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Framework.DependencyInjection;
|
using Microsoft.AspNet.Mvc.Internal;
|
||||||
using Microsoft.Framework.Internal;
|
using Microsoft.Framework.Internal;
|
||||||
using Microsoft.Framework.OptionsModel;
|
|
||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
|
@ -18,13 +15,11 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class JsonResult : ActionResult
|
public class JsonResult : ActionResult
|
||||||
{
|
{
|
||||||
/// <summary>
|
private readonly JsonSerializerSettings _serializerSettings;
|
||||||
/// The list of content-types used for formatting when <see cref="ContentTypes"/> is null or empty.
|
|
||||||
/// </summary>
|
private static readonly MediaTypeHeaderValue DefaultContentType = new MediaTypeHeaderValue("application/json")
|
||||||
public static readonly IReadOnlyList<MediaTypeHeaderValue> DefaultContentTypes = new MediaTypeHeaderValue[]
|
|
||||||
{
|
{
|
||||||
MediaTypeHeaderValue.Parse("application/json"),
|
Encoding = Encoding.UTF8
|
||||||
MediaTypeHeaderValue.Parse("text/json"),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -32,7 +27,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value">The value to format as JSON.</param>
|
/// <param name="value">The value to format as JSON.</param>
|
||||||
public JsonResult(object value)
|
public JsonResult(object value)
|
||||||
: this(value, formatter: null)
|
: this(value, serializerSettings: SerializerSettingsProvider.CreateSerializerSettings())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,32 +38,15 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// <param name="serializerSettings">The <see cref="JsonSerializerSettings"/> to be used by
|
/// <param name="serializerSettings">The <see cref="JsonSerializerSettings"/> to be used by
|
||||||
/// the formatter.</param>
|
/// the formatter.</param>
|
||||||
public JsonResult(object value, [NotNull] JsonSerializerSettings serializerSettings)
|
public JsonResult(object value, [NotNull] JsonSerializerSettings serializerSettings)
|
||||||
: this(value, formatter: new JsonOutputFormatter(serializerSettings))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new <see cref="JsonResult"/> with the given <paramref name="value"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">The value to format as JSON.</param>
|
|
||||||
/// <param name="formatter">The formatter to use, or <c>null</c> to choose a formatter dynamically.</param>
|
|
||||||
public JsonResult(object value, IOutputFormatter formatter)
|
|
||||||
{
|
{
|
||||||
Value = value;
|
Value = value;
|
||||||
Formatter = formatter;
|
_serializerSettings = serializerSettings;
|
||||||
|
|
||||||
ContentTypes = new List<MediaTypeHeaderValue>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the list of supported Content-Types.
|
/// Gets or sets the <see cref="MediaTypeHeaderValue"/> representing the Content-Type header of the response.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IList<MediaTypeHeaderValue> ContentTypes { get; set; }
|
public MediaTypeHeaderValue ContentType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the formatter.
|
|
||||||
/// </summary>
|
|
||||||
public IOutputFormatter Formatter { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the HTTP status code.
|
/// Gets or sets the HTTP status code.
|
||||||
|
|
@ -81,80 +59,44 @@ namespace Microsoft.AspNet.Mvc
|
||||||
public object Value { get; set; }
|
public object Value { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override async Task ExecuteResultAsync([NotNull] ActionContext context)
|
public override Task ExecuteResultAsync([NotNull] ActionContext context)
|
||||||
{
|
{
|
||||||
var objectResult = new ObjectResult(Value);
|
var response = context.HttpContext.Response;
|
||||||
|
|
||||||
// Set the content type explicitly to application/json and text/json.
|
var contentTypeHeader = ContentType;
|
||||||
// if the user has not already set it.
|
if (contentTypeHeader == null)
|
||||||
if (ContentTypes == null || ContentTypes.Count == 0)
|
|
||||||
{
|
{
|
||||||
foreach (var contentType in DefaultContentTypes)
|
contentTypeHeader = DefaultContentType;
|
||||||
{
|
|
||||||
objectResult.ContentTypes.Add(contentType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
objectResult.ContentTypes = ContentTypes;
|
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 = Encoding.UTF8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var formatterContext = new OutputFormatterContext()
|
response.ContentType = contentTypeHeader.ToString();
|
||||||
{
|
|
||||||
HttpContext = context.HttpContext,
|
|
||||||
DeclaredType = objectResult.DeclaredType,
|
|
||||||
Object = Value,
|
|
||||||
};
|
|
||||||
|
|
||||||
// JsonResult expects to always find a formatter, in contrast with ObjectResult, which might return
|
|
||||||
// a 406.
|
|
||||||
var formatter = SelectFormatter(objectResult, formatterContext);
|
|
||||||
Debug.Assert(formatter != null);
|
|
||||||
|
|
||||||
if (StatusCode != null)
|
if (StatusCode != null)
|
||||||
{
|
{
|
||||||
context.HttpContext.Response.StatusCode = StatusCode.Value;
|
response.StatusCode = StatusCode.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
await formatter.WriteAsync(formatterContext);
|
using (var writer = new HttpResponseStreamWriter(response.Body, contentTypeHeader.Encoding))
|
||||||
}
|
|
||||||
|
|
||||||
private IOutputFormatter SelectFormatter(ObjectResult objectResult, OutputFormatterContext formatterContext)
|
|
||||||
{
|
|
||||||
if (Formatter == null)
|
|
||||||
{
|
{
|
||||||
// If no formatter was provided, then run Conneg with the formatters configured in options.
|
using (var jsonWriter = new JsonTextWriter(writer))
|
||||||
var formatters = formatterContext
|
|
||||||
.HttpContext
|
|
||||||
.RequestServices
|
|
||||||
.GetRequiredService<IOptions<MvcOptions>>()
|
|
||||||
.Options
|
|
||||||
.OutputFormatters
|
|
||||||
.OfType<JsonOutputFormatter>()
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
var formatter = objectResult.SelectFormatter(formatterContext, formatters);
|
|
||||||
if (formatter == null)
|
|
||||||
{
|
{
|
||||||
// If the available user-configured formatters can't write this type, then fall back to the
|
jsonWriter.CloseOutput = false;
|
||||||
// 'global' one.
|
var jsonSerializer = JsonSerializer.Create(_serializerSettings);
|
||||||
formatter = formatterContext
|
jsonSerializer.Serialize(jsonWriter, Value);
|
||||||
.HttpContext
|
|
||||||
.RequestServices
|
|
||||||
.GetRequiredService<JsonOutputFormatter>();
|
|
||||||
|
|
||||||
// Run SelectFormatter again to try to choose a content type that this formatter can do.
|
|
||||||
objectResult.SelectFormatter(formatterContext, new[] { formatter });
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return formatter;
|
return Task.FromResult(true);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Run SelectFormatter to try to choose a content type that this formatter can do.
|
|
||||||
objectResult.SelectFormatter(formatterContext, new[] { Formatter });
|
|
||||||
return Formatter;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +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.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Framework.DependencyInjection;
|
using Microsoft.AspNet.Mvc.Internal;
|
||||||
using Microsoft.Framework.Internal;
|
using Microsoft.Framework.Internal;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
|
@ -13,12 +13,14 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class JsonViewComponentResult : IViewComponentResult
|
public class JsonViewComponentResult : IViewComponentResult
|
||||||
{
|
{
|
||||||
|
private readonly JsonSerializerSettings _serializerSettings;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new <see cref="JsonViewComponentResult"/>.
|
/// Initializes a new <see cref="JsonViewComponentResult"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value">The value to format as JSON text.</param>
|
/// <param name="value">The value to format as JSON text.</param>
|
||||||
public JsonViewComponentResult(object value)
|
public JsonViewComponentResult(object value)
|
||||||
: this(value, formatter: null)
|
: this(value, serializerSettings: SerializerSettingsProvider.CreateSerializerSettings())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -29,19 +31,9 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// <param name="serializerSettings">The <see cref="JsonSerializerSettings"/> to be used by
|
/// <param name="serializerSettings">The <see cref="JsonSerializerSettings"/> to be used by
|
||||||
/// the formatter.</param>
|
/// the formatter.</param>
|
||||||
public JsonViewComponentResult(object value, [NotNull] JsonSerializerSettings serializerSettings)
|
public JsonViewComponentResult(object value, [NotNull] JsonSerializerSettings serializerSettings)
|
||||||
: this(value, new JsonOutputFormatter(serializerSettings))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new <see cref="JsonViewComponentResult"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">The value to format as JSON text.</param>
|
|
||||||
/// <param name="formatter">The <see cref="JsonOutputFormatter"/> to use.</param>
|
|
||||||
public JsonViewComponentResult(object value, JsonOutputFormatter formatter)
|
|
||||||
{
|
{
|
||||||
Value = value;
|
Value = value;
|
||||||
Formatter = formatter;
|
_serializerSettings = serializerSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -49,19 +41,18 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public object Value { get; }
|
public object Value { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the formatter.
|
|
||||||
/// </summary>
|
|
||||||
public JsonOutputFormatter Formatter { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Renders JSON text to the output.
|
/// Renders JSON text to the output.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="context">The <see cref="ViewComponentContext"/>.</param>
|
/// <param name="context">The <see cref="ViewComponentContext"/>.</param>
|
||||||
public void Execute([NotNull] ViewComponentContext context)
|
public void Execute([NotNull] ViewComponentContext context)
|
||||||
{
|
{
|
||||||
var formatter = Formatter ?? ResolveFormatter(context);
|
using (var jsonWriter = new JsonTextWriter(context.Writer))
|
||||||
formatter.WriteObject(context.Writer, Value);
|
{
|
||||||
|
jsonWriter.CloseOutput = false;
|
||||||
|
var jsonSerializer = JsonSerializer.Create(_serializerSettings);
|
||||||
|
jsonSerializer.Serialize(jsonWriter, Value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -74,11 +65,5 @@ namespace Microsoft.AspNet.Mvc
|
||||||
Execute(context);
|
Execute(context);
|
||||||
return Task.FromResult(true);
|
return Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static JsonOutputFormatter ResolveFormatter(ViewComponentContext context)
|
|
||||||
{
|
|
||||||
var services = context.ViewContext.HttpContext.RequestServices;
|
|
||||||
return services.GetRequiredService<JsonOutputFormatter>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding.Validation;
|
using Microsoft.AspNet.Mvc.ModelBinding.Validation;
|
||||||
using Microsoft.AspNet.Mvc.WebApiCompatShim;
|
using Microsoft.AspNet.Mvc.WebApiCompatShim;
|
||||||
using Microsoft.Framework.Internal;
|
using Microsoft.Framework.Internal;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace System.Web.Http
|
namespace System.Web.Http
|
||||||
|
|
@ -257,9 +258,7 @@ namespace System.Web.Http
|
||||||
[NonAction]
|
[NonAction]
|
||||||
public virtual JsonResult Json<T>([NotNull] T content, [NotNull] JsonSerializerSettings serializerSettings)
|
public virtual JsonResult Json<T>([NotNull] T content, [NotNull] JsonSerializerSettings serializerSettings)
|
||||||
{
|
{
|
||||||
var formatter = new JsonOutputFormatter(serializerSettings);
|
return new JsonResult(content, serializerSettings);
|
||||||
|
|
||||||
return new JsonResult(content, formatter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -276,12 +275,13 @@ namespace System.Web.Http
|
||||||
[NotNull] JsonSerializerSettings serializerSettings,
|
[NotNull] JsonSerializerSettings serializerSettings,
|
||||||
[NotNull] Encoding encoding)
|
[NotNull] Encoding encoding)
|
||||||
{
|
{
|
||||||
var formatter = new JsonOutputFormatter(serializerSettings);
|
var result = new JsonResult(content, serializerSettings);
|
||||||
|
result.ContentType = new MediaTypeHeaderValue("application/json")
|
||||||
|
{
|
||||||
|
Encoding = encoding
|
||||||
|
};
|
||||||
|
|
||||||
formatter.SupportedEncodings.Clear();
|
return result;
|
||||||
formatter.SupportedEncodings.Add(encoding);
|
|
||||||
|
|
||||||
return new JsonResult(content, formatter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -1033,7 +1033,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Controller_Json_WithParameterValueAndSerializerSettings_SetsRespectiveValues()
|
public void Controller_Json_WithParameterValue_SetsRespectiveProperty()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var controller = new TestableController();
|
var controller = new TestableController();
|
||||||
|
|
@ -1046,8 +1046,6 @@ namespace Microsoft.AspNet.Mvc.Test
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsType<JsonResult>(actualJsonResult);
|
Assert.IsType<JsonResult>(actualJsonResult);
|
||||||
Assert.Same(data, actualJsonResult.Value);
|
Assert.Same(data, actualJsonResult.Value);
|
||||||
var jsonFormatter = actualJsonResult.Formatter as JsonOutputFormatter;
|
|
||||||
Assert.Same(serializerSettings, jsonFormatter.SerializerSettings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -1094,8 +1092,6 @@ namespace Microsoft.AspNet.Mvc.Test
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsType<JsonResult>(result);
|
Assert.IsType<JsonResult>(result);
|
||||||
Assert.Same(input, result.Value);
|
Assert.Same(input, result.Value);
|
||||||
var jsonFormatter = result.Formatter as JsonOutputFormatter;
|
|
||||||
Assert.Same(serializerSettings, jsonFormatter.SerializerSettings);
|
|
||||||
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>()),
|
||||||
Times.Once());
|
Times.Once());
|
||||||
|
|
|
||||||
|
|
@ -228,8 +228,6 @@ namespace Microsoft.AspNet.Mvc
|
||||||
Assert.NotNull(jsonResult.Value);
|
Assert.NotNull(jsonResult.Value);
|
||||||
Assert.Same(model, jsonResult.Value);
|
Assert.Same(model, jsonResult.Value);
|
||||||
Assert.IsType<MyModel>(jsonResult.Value);
|
Assert.IsType<MyModel>(jsonResult.Value);
|
||||||
var jsonFormatter = jsonResult.Formatter as JsonOutputFormatter;
|
|
||||||
Assert.Same(serializerSettings, jsonFormatter.SerializerSettings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
|
|
@ -1,19 +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.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
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.Http.Internal;
|
using Microsoft.AspNet.Http.Internal;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
using Microsoft.Framework.Logging;
|
|
||||||
using Microsoft.Framework.OptionsModel;
|
|
||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
using Moq;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -28,18 +22,12 @@ namespace Microsoft.AspNet.Mvc
|
||||||
= new byte[] { 123, 13, 10, 32, 32, 34, 102, 111, 111, 34, 58, 32, 34, 97, 98, 99, 100, 34, 13, 10, 125 };
|
= new byte[] { 123, 13, 10, 32, 32, 34, 102, 111, 111, 34, 58, 32, 34, 97, 98, 99, 100, 34, 13, 10, 125 };
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ExecuteResultAsync_OptionsFormatter_WithoutBOM()
|
public async Task ExecuteResultAsync_UsesDefaultContentType_IfNoContentTypeSpecified()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected = _abcdUTF8Bytes;
|
var expected = _abcdUTF8Bytes;
|
||||||
|
|
||||||
var optionsFormatters = new List<IOutputFormatter>()
|
var context = GetHttpContext();
|
||||||
{
|
|
||||||
Mock.Of<IOutputFormatter>(), // This won't be used
|
|
||||||
new JsonOutputFormatter(),
|
|
||||||
};
|
|
||||||
|
|
||||||
var context = GetHttpContext(optionsFormatters);
|
|
||||||
var actionContext = new ActionContext(context, new RouteData(), new ActionDescriptor());
|
var actionContext = new ActionContext(context, new RouteData(), new ActionDescriptor());
|
||||||
|
|
||||||
var result = new JsonResult(new { foo = "abcd" });
|
var result = new JsonResult(new { foo = "abcd" });
|
||||||
|
|
@ -54,49 +42,16 @@ namespace Microsoft.AspNet.Mvc
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ExecuteResultAsync_Null()
|
public async Task ExecuteResultAsync_NullEncoding_SetsContentTypeAndDefaultEncoding()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected = _abcdUTF8Bytes;
|
var expected = _abcdUTF8Bytes;
|
||||||
|
|
||||||
var optionsFormatters = new List<IOutputFormatter>()
|
var context = GetHttpContext();
|
||||||
{
|
|
||||||
Mock.Of<IOutputFormatter>(), // This won't be used
|
|
||||||
new JsonOutputFormatter(),
|
|
||||||
};
|
|
||||||
|
|
||||||
var context = GetHttpContext(optionsFormatters);
|
|
||||||
var actionContext = new ActionContext(context, new RouteData(), new ActionDescriptor());
|
|
||||||
|
|
||||||
var result = new JsonResult(new { foo = "abcd" });
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await result.ExecuteResultAsync(actionContext);
|
|
||||||
var written = GetWrittenBytes(context);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Equal(expected, written);
|
|
||||||
Assert.Equal("application/json; charset=utf-8", context.Response.ContentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task ExecuteResultAsync_OptionsFormatter_Conneg()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var expected = _abcdUTF8Bytes;
|
|
||||||
|
|
||||||
var optionsFormatters = new List<IOutputFormatter>()
|
|
||||||
{
|
|
||||||
Mock.Of<IOutputFormatter>(), // This won't be used
|
|
||||||
new JsonOutputFormatter(),
|
|
||||||
};
|
|
||||||
|
|
||||||
var context = GetHttpContext(optionsFormatters);
|
|
||||||
context.Request.Headers["Accept"] = "text/json";
|
|
||||||
|
|
||||||
var actionContext = new ActionContext(context, new RouteData(), new ActionDescriptor());
|
var actionContext = new ActionContext(context, new RouteData(), new ActionDescriptor());
|
||||||
|
|
||||||
var result = new JsonResult(new { foo = "abcd" });
|
var result = new JsonResult(new { foo = "abcd" });
|
||||||
|
result.ContentType = new MediaTypeHeaderValue("text/json");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await result.ExecuteResultAsync(actionContext);
|
await result.ExecuteResultAsync(actionContext);
|
||||||
|
|
@ -108,7 +63,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ExecuteResultAsync_UsesPassedInFormatter()
|
public async Task ExecuteResultAsync_SetsContentTypeAndEncoding()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var expected = _abcdUTF8Bytes;
|
var expected = _abcdUTF8Bytes;
|
||||||
|
|
@ -116,13 +71,11 @@ namespace Microsoft.AspNet.Mvc
|
||||||
var context = GetHttpContext();
|
var context = GetHttpContext();
|
||||||
var actionContext = new ActionContext(context, new RouteData(), new ActionDescriptor());
|
var actionContext = new ActionContext(context, new RouteData(), new ActionDescriptor());
|
||||||
|
|
||||||
var formatter = new JsonOutputFormatter();
|
var result = new JsonResult(new { foo = "abcd" });
|
||||||
formatter.SupportedEncodings.Clear();
|
result.ContentType = new MediaTypeHeaderValue("text/json")
|
||||||
|
{
|
||||||
// This is UTF-8 WITH BOM
|
Encoding = Encoding.ASCII
|
||||||
formatter.SupportedEncodings.Add(Encoding.UTF8);
|
};
|
||||||
|
|
||||||
var result = new JsonResult(new { foo = "abcd" }, formatter);
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await result.ExecuteResultAsync(actionContext);
|
await result.ExecuteResultAsync(actionContext);
|
||||||
|
|
@ -130,31 +83,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(expected, written);
|
Assert.Equal(expected, written);
|
||||||
Assert.Equal("application/json; charset=utf-8", context.Response.ContentType);
|
Assert.Equal("text/json; charset=us-ascii", context.Response.ContentType);
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task ExecuteResultAsync_UsesPassedInFormatter_ContentTypeSpecified()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var expected = _abcdUTF8Bytes;
|
|
||||||
|
|
||||||
var context = GetHttpContext();
|
|
||||||
var actionContext = new ActionContext(context, new RouteData(), new ActionDescriptor());
|
|
||||||
|
|
||||||
var formatter = new JsonOutputFormatter();
|
|
||||||
formatter.SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/hal+json"));
|
|
||||||
|
|
||||||
var result = new JsonResult(new { foo = "abcd" }, formatter);
|
|
||||||
result.ContentTypes.Add(MediaTypeHeaderValue.Parse("application/hal+json"));
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await result.ExecuteResultAsync(actionContext);
|
|
||||||
var written = GetWrittenBytes(context);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Equal(expected, written);
|
|
||||||
Assert.Equal("application/hal+json; charset=utf-8", context.Response.ContentType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -180,67 +109,11 @@ namespace Microsoft.AspNet.Mvc
|
||||||
Assert.Equal("application/json; charset=utf-8", context.Response.ContentType);
|
Assert.Equal("application/json; charset=utf-8", context.Response.ContentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no formatter in options can match the given content-types, then use the one registered
|
private HttpContext GetHttpContext()
|
||||||
// in services
|
|
||||||
[Fact]
|
|
||||||
public async Task ExecuteResultAsync_UsesGlobalFormatter_IfNoFormatterIsConfigured()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var expected = _abcdUTF8Bytes;
|
|
||||||
|
|
||||||
var context = GetHttpContext(enableFallback: true);
|
|
||||||
var actionContext = new ActionContext(context, new RouteData(), new ActionDescriptor());
|
|
||||||
|
|
||||||
var result = new JsonResult(new { foo = "abcd" });
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await result.ExecuteResultAsync(actionContext);
|
|
||||||
var written = GetWrittenBytes(context);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Equal(expected, written);
|
|
||||||
Assert.Equal("application/json; charset=utf-8", context.Response.ContentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpContext GetHttpContext(
|
|
||||||
IReadOnlyList<IOutputFormatter> outputFormatters = null,
|
|
||||||
bool enableFallback = false)
|
|
||||||
{
|
{
|
||||||
var httpContext = new DefaultHttpContext();
|
var httpContext = new DefaultHttpContext();
|
||||||
httpContext.Response.Body = new MemoryStream();
|
httpContext.Response.Body = new MemoryStream();
|
||||||
|
|
||||||
var services = new Mock<IServiceProvider>(MockBehavior.Strict);
|
|
||||||
httpContext.RequestServices = services.Object;
|
|
||||||
|
|
||||||
var options = new MvcOptions();
|
|
||||||
if (outputFormatters != null)
|
|
||||||
{
|
|
||||||
foreach (var formatter in outputFormatters)
|
|
||||||
{
|
|
||||||
options.OutputFormatters.Add(formatter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var optionsAccessor = new Mock<IOptions<MvcOptions>>();
|
|
||||||
optionsAccessor.SetupGet(o => o.Options)
|
|
||||||
.Returns(options);
|
|
||||||
|
|
||||||
services.Setup(s => s.GetService(typeof(IOptions<MvcOptions>)))
|
|
||||||
.Returns(optionsAccessor.Object);
|
|
||||||
services.Setup(s => s.GetService(typeof(IOptions<MvcOptions>)))
|
|
||||||
.Returns(optionsAccessor.Object);
|
|
||||||
services.Setup(s => s.GetService(typeof(ILogger<ObjectResult>)))
|
|
||||||
.Returns(new Mock<ILogger<ObjectResult>>().Object);
|
|
||||||
|
|
||||||
// This is the ultimate fallback, it will be used if none of the formatters from options
|
|
||||||
// work.
|
|
||||||
if (enableFallback)
|
|
||||||
{
|
|
||||||
services
|
|
||||||
.Setup(s => s.GetService(typeof(JsonOutputFormatter)))
|
|
||||||
.Returns(new JsonOutputFormatter());
|
|
||||||
}
|
|
||||||
|
|
||||||
return httpContext;
|
return httpContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +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 Microsoft.AspNet.Http.Internal;
|
using Microsoft.AspNet.Http.Internal;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNet.Mvc.Rendering;
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
using Microsoft.AspNet.Mvc.ViewComponents;
|
using Microsoft.AspNet.Mvc.ViewComponents;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
using Microsoft.Framework.DependencyInjection;
|
|
||||||
using Moq;
|
using Moq;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -17,26 +16,6 @@ namespace Microsoft.AspNet.Mvc
|
||||||
{
|
{
|
||||||
public class JsonViewComponentResultTest
|
public class JsonViewComponentResultTest
|
||||||
{
|
{
|
||||||
[Fact]
|
|
||||||
public void Execute_SerializesData_UsingSpecifiedFormatter()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var view = Mock.Of<IView>();
|
|
||||||
var buffer = new MemoryStream();
|
|
||||||
var viewComponentContext = GetViewComponentContext(view, buffer);
|
|
||||||
|
|
||||||
var expectedFormatter = new JsonOutputFormatter();
|
|
||||||
var result = new JsonViewComponentResult(1, expectedFormatter);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
result.Execute(viewComponentContext);
|
|
||||||
buffer.Position = 0;
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Equal(expectedFormatter, result.Formatter);
|
|
||||||
Assert.Equal("1", new StreamReader(buffer).ReadToEnd());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Execute_UsesFormatter_WithSpecifiedSerializerSettings()
|
public void Execute_UsesFormatter_WithSpecifiedSerializerSettings()
|
||||||
{
|
{
|
||||||
|
|
@ -48,65 +27,14 @@ namespace Microsoft.AspNet.Mvc
|
||||||
var serializerSettings = new JsonSerializerSettings();
|
var serializerSettings = new JsonSerializerSettings();
|
||||||
serializerSettings.Formatting = Formatting.Indented;
|
serializerSettings.Formatting = Formatting.Indented;
|
||||||
|
|
||||||
var result = new JsonViewComponentResult("abc", serializerSettings);
|
var result = new JsonViewComponentResult(new { foo = "abcd" }, serializerSettings);
|
||||||
|
viewComponentContext.ViewContext.HttpContext.Response.Body = buffer;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
result.Execute(viewComponentContext);
|
result.Execute(viewComponentContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Same(serializerSettings, result.Formatter.SerializerSettings);
|
Assert.Equal("{\r\n \"foo\": \"abcd\"\r\n}", Encoding.UTF8.GetString(buffer.ToArray()));
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Execute_FallsbackToServices_WhenNoJsonFormatterIsProvided()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var view = Mock.Of<IView>();
|
|
||||||
|
|
||||||
var serviceProvider = new Mock<IServiceProvider>();
|
|
||||||
|
|
||||||
serviceProvider
|
|
||||||
.Setup(p => p.GetService(typeof(JsonOutputFormatter)))
|
|
||||||
.Returns(new JsonOutputFormatter())
|
|
||||||
.Verifiable();
|
|
||||||
|
|
||||||
var buffer = new MemoryStream();
|
|
||||||
|
|
||||||
var result = new JsonViewComponentResult(1);
|
|
||||||
var viewComponentContext = GetViewComponentContext(view, buffer);
|
|
||||||
viewComponentContext.ViewContext.HttpContext.RequestServices = serviceProvider.Object;
|
|
||||||
|
|
||||||
// Act
|
|
||||||
result.Execute(viewComponentContext);
|
|
||||||
buffer.Position = 0;
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Equal("1", new StreamReader(buffer).ReadToEnd());
|
|
||||||
serviceProvider.Verify();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Execute_Throws_IfNoFormatterCanBeResolved()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var expected = "No service for type 'Microsoft.AspNet.Mvc.JsonOutputFormatter'" +
|
|
||||||
" has been registered.";
|
|
||||||
|
|
||||||
var view = Mock.Of<IView>();
|
|
||||||
|
|
||||||
var serviceProvider = new ServiceCollection().BuildServiceProvider();
|
|
||||||
|
|
||||||
var buffer = new MemoryStream();
|
|
||||||
|
|
||||||
var result = new JsonViewComponentResult(1);
|
|
||||||
var viewComponentContext = GetViewComponentContext(view, buffer);
|
|
||||||
viewComponentContext.ViewContext.HttpContext.RequestServices = serviceProvider;
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var ex = Assert.Throws<InvalidOperationException>(() => result.Execute(viewComponentContext));
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Equal(expected, ex.Message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ViewComponentContext GetViewComponentContext(IView view, Stream stream)
|
private static ViewComponentContext GetViewComponentContext(IView view, Stream stream)
|
||||||
|
|
|
||||||
|
|
@ -319,80 +319,6 @@ END:VCARD
|
||||||
Assert.Equal(expectedBody, body);
|
Assert.Equal(expectedBody, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task JsonResult_UsesDefaultContentTypes_IfNoneAreAddedExplicitly()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
|
||||||
var client = server.CreateClient();
|
|
||||||
var expectedContentType = MediaTypeHeaderValue.Parse("application/json;charset=utf-8");
|
|
||||||
var expectedBody = "{\"MethodName\":\"ReturnJsonResult\"}";
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var response = await client.GetAsync("http://localhost/JsonResult/ReturnJsonResult");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Equal(expectedContentType, response.Content.Headers.ContentType);
|
|
||||||
var body = await response.Content.ReadAsStringAsync();
|
|
||||||
Assert.Equal(expectedBody, body);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task JsonResult_UsesExplicitContentTypeAndFormatter_IfAdded()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
|
||||||
var client = server.CreateClient();
|
|
||||||
var expectedContentType = MediaTypeHeaderValue.Parse("application/custom-json;charset=utf-8");
|
|
||||||
var expectedBody = "{ MethodName = ReturnJsonResult_WithCustomMediaType }";
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var response = await client.GetAsync("http://localhost/JsonResult/ReturnJsonResult_WithCustomMediaType");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Equal(expectedContentType, response.Content.Headers.ContentType);
|
|
||||||
var body = await response.Content.ReadAsStringAsync();
|
|
||||||
Assert.Equal(expectedBody, body);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task JsonResult_UsesDefaultJsonFormatter_IfNoMatchingFormatterIsFound()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
|
||||||
var client = server.CreateClient();
|
|
||||||
var expectedContentType = MediaTypeHeaderValue.Parse("application/json;charset=utf-8");
|
|
||||||
var expectedBody = "{\"MethodName\":\"ReturnJsonResult_WithCustomMediaType_NoFormatter\"}";
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var response = await client.GetAsync("http://localhost/JsonResult/ReturnJsonResult_WithCustomMediaType_NoFormatter");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Equal(expectedContentType, response.Content.Headers.ContentType);
|
|
||||||
var body = await response.Content.ReadAsStringAsync();
|
|
||||||
Assert.Equal(expectedBody, body);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task JsonFormatter_SupportedMediaType_DoesNotChangeAcrossRequests()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
|
||||||
var client = server.CreateClient();
|
|
||||||
var expectedContentType = MediaTypeHeaderValue.Parse("application/json;charset=utf-8");
|
|
||||||
var expectedBody = "{\"MethodName\":\"ReturnJsonResult\"}";
|
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++)
|
|
||||||
{
|
|
||||||
// Act and Assert
|
|
||||||
var response = await client.GetAsync("http://localhost/JsonResult/ReturnJsonResult");
|
|
||||||
|
|
||||||
Assert.Equal(expectedContentType, response.Content.Headers.ContentType);
|
|
||||||
var body = await response.Content.ReadAsStringAsync();
|
|
||||||
Assert.Equal(expectedBody, body);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task XmlFormatter_SupportedMediaType_DoesNotChangeAcrossRequests()
|
public async Task XmlFormatter_SupportedMediaType_DoesNotChangeAcrossRequests()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,8 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||||
private readonly Action<IApplicationBuilder> _app = new BasicWebSite.Startup().Configure;
|
private readonly Action<IApplicationBuilder> _app = new BasicWebSite.Startup().Configure;
|
||||||
private readonly Action<IServiceCollection> _configureServices = new BasicWebSite.Startup().ConfigureServices;
|
private readonly Action<IServiceCollection> _configureServices = new BasicWebSite.Startup().ConfigureServices;
|
||||||
|
|
||||||
[Theory]
|
[Fact]
|
||||||
[InlineData("application/json")]
|
public async Task JsonResult_UsesDefaultContentType()
|
||||||
[InlineData("text/json")]
|
|
||||||
public async Task JsonResult_Conneg(string mediaType)
|
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
||||||
|
|
@ -29,7 +27,6 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||||
var url = "http://localhost/JsonResult/Plain";
|
var url = "http://localhost/JsonResult/Plain";
|
||||||
|
|
||||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||||
request.Headers.TryAddWithoutValidation("Accept", mediaType);
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await client.SendAsync(request);
|
var response = await client.SendAsync(request);
|
||||||
|
|
@ -37,7 +34,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.Equal(mediaType, response.Content.Headers.ContentType.MediaType);
|
Assert.Equal("application/json", response.Content.Headers.ContentType.MediaType);
|
||||||
Assert.Equal("{\"Message\":\"hello\"}", content);
|
Assert.Equal("{\"Message\":\"hello\"}", content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,56 +108,6 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||||
Assert.Equal("\"hello\"", content);
|
Assert.Equal("\"hello\"", content);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData("application/json")]
|
|
||||||
[InlineData("text/json")]
|
|
||||||
public async Task JsonResult_CustomFormatter_Conneg(string mediaType)
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
|
||||||
var client = server.CreateClient();
|
|
||||||
|
|
||||||
var url = "http://localhost/JsonResult/CustomFormatter";
|
|
||||||
|
|
||||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
|
||||||
request.Headers.TryAddWithoutValidation("Accept", mediaType);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var response = await client.SendAsync(request);
|
|
||||||
var content = await response.Content.ReadAsStringAsync();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
||||||
Assert.Equal(mediaType, response.Content.Headers.ContentType.MediaType);
|
|
||||||
Assert.Equal("{\"message\":\"hello\"}", content);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Using an Accept header can't force Json to not be Json. If your accept header doesn't jive with the
|
|
||||||
// formatters/content-type configured on the result it will be ignored.
|
|
||||||
[Theory]
|
|
||||||
[InlineData("application/xml")]
|
|
||||||
[InlineData("text/xml")]
|
|
||||||
public async Task JsonResult_CustomFormatter_Conneg_Fails(string mediaType)
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
|
|
||||||
var client = server.CreateClient();
|
|
||||||
|
|
||||||
var url = "http://localhost/JsonResult/CustomFormatter";
|
|
||||||
|
|
||||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
|
||||||
request.Headers.TryAddWithoutValidation("Accept", mediaType);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var response = await client.SendAsync(request);
|
|
||||||
var content = await response.Content.ReadAsStringAsync();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
||||||
Assert.Equal("application/json", response.Content.Headers.ContentType.MediaType);
|
|
||||||
Assert.Equal("{\"message\":\"hello\"}", content);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task JsonResult_Uses_CustomSerializerSettings()
|
public async Task JsonResult_Uses_CustomSerializerSettings()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -250,26 +250,7 @@ namespace System.Web.Http
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ApiController_Json_Settings()
|
public void ApiController_Json_Encoding()
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var controller = new ConcreteApiController();
|
|
||||||
var product = new Product();
|
|
||||||
var settings = new JsonSerializerSettings();
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var result = controller.Json(product, settings);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var jsonResult = Assert.IsType<JsonResult>(result);
|
|
||||||
Assert.Same(product, jsonResult.Value);
|
|
||||||
|
|
||||||
var formatter = Assert.IsType<JsonOutputFormatter>(jsonResult.Formatter);
|
|
||||||
Assert.Same(settings, formatter.SerializerSettings);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void ApiController_Json_Settings_Encoding()
|
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var controller = new ConcreteApiController();
|
var controller = new ConcreteApiController();
|
||||||
|
|
@ -283,9 +264,7 @@ namespace System.Web.Http
|
||||||
var jsonResult = Assert.IsType<JsonResult>(result);
|
var jsonResult = Assert.IsType<JsonResult>(result);
|
||||||
Assert.Same(product, jsonResult.Value);
|
Assert.Same(product, jsonResult.Value);
|
||||||
|
|
||||||
var formatter = Assert.IsType<JsonOutputFormatter>(jsonResult.Formatter);
|
Assert.Same(Encoding.UTF8, jsonResult.ContentType.Encoding);
|
||||||
Assert.Same(settings, formatter.SerializerSettings);
|
|
||||||
Assert.Same(Encoding.UTF8, Assert.Single(formatter.SupportedEncodings));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
|
|
@ -17,21 +17,10 @@ namespace BasicWebSite.Controllers
|
||||||
return Json(new { Message = "hello" });
|
return Json(new { Message = "hello" });
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonResult CustomFormatter()
|
|
||||||
{
|
|
||||||
var formatter = new JsonOutputFormatter();
|
|
||||||
formatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
|
|
||||||
|
|
||||||
return new JsonResult(new { Message = "hello" }, formatter);
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonResult CustomContentType()
|
public JsonResult CustomContentType()
|
||||||
{
|
{
|
||||||
var formatter = new JsonOutputFormatter();
|
var result = new JsonResult(new { Message = "hello" });
|
||||||
formatter.SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/message+json"));
|
result.ContentType = MediaTypeHeaderValue.Parse("application/message+json");
|
||||||
|
|
||||||
var result = new JsonResult(new { Message = "hello" }, formatter);
|
|
||||||
result.ContentTypes.Add(MediaTypeHeaderValue.Parse("application/message+json"));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,32 +2,11 @@
|
||||||
// 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 ContentNegotiationWebSite
|
namespace ContentNegotiationWebSite
|
||||||
{
|
{
|
||||||
public class JsonResultController : Controller
|
public class JsonResultController : Controller
|
||||||
{
|
{
|
||||||
public IActionResult ReturnJsonResult()
|
|
||||||
{
|
|
||||||
return new JsonResult(new { MethodName = "ReturnJsonResult" });
|
|
||||||
}
|
|
||||||
|
|
||||||
public IActionResult ReturnJsonResult_WithCustomMediaType()
|
|
||||||
{
|
|
||||||
var jsonResult = new JsonResult(new { MethodName = "ReturnJsonResult_WithCustomMediaType" },
|
|
||||||
new CustomFormatter("application/custom-json"));
|
|
||||||
jsonResult.ContentTypes.Add(MediaTypeHeaderValue.Parse("application/custom-json"));
|
|
||||||
return jsonResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IActionResult ReturnJsonResult_WithCustomMediaType_NoFormatter()
|
|
||||||
{
|
|
||||||
var jsonResult = new JsonResult(new { MethodName = "ReturnJsonResult_WithCustomMediaType_NoFormatter" });
|
|
||||||
jsonResult.ContentTypes.Add(MediaTypeHeaderValue.Parse("application/custom-json"));
|
|
||||||
return jsonResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Produces("application/xml")]
|
[Produces("application/xml")]
|
||||||
public IActionResult Produces_WithNonObjectResult()
|
public IActionResult Produces_WithNonObjectResult()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue