diff --git a/src/Microsoft.AspNet.Mvc.Extensions/JsonResult.cs b/src/Microsoft.AspNet.Mvc.Extensions/JsonResult.cs
index dc036ce5be..e4cfdfe4c1 100644
--- a/src/Microsoft.AspNet.Mvc.Extensions/JsonResult.cs
+++ b/src/Microsoft.AspNet.Mvc.Extensions/JsonResult.cs
@@ -1,13 +1,10 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
+using System.Text;
using System.Threading.Tasks;
-using Microsoft.Framework.DependencyInjection;
+using Microsoft.AspNet.Mvc.Internal;
using Microsoft.Framework.Internal;
-using Microsoft.Framework.OptionsModel;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;
@@ -18,13 +15,11 @@ namespace Microsoft.AspNet.Mvc
///
public class JsonResult : ActionResult
{
- ///
- /// The list of content-types used for formatting when is null or empty.
- ///
- public static readonly IReadOnlyList DefaultContentTypes = new MediaTypeHeaderValue[]
+ private readonly JsonSerializerSettings _serializerSettings;
+
+ private static readonly MediaTypeHeaderValue DefaultContentType = new MediaTypeHeaderValue("application/json")
{
- MediaTypeHeaderValue.Parse("application/json"),
- MediaTypeHeaderValue.Parse("text/json"),
+ Encoding = Encoding.UTF8
};
///
@@ -32,7 +27,7 @@ namespace Microsoft.AspNet.Mvc
///
/// The value to format as JSON.
public JsonResult(object value)
- : this(value, formatter: null)
+ : this(value, serializerSettings: SerializerSettingsProvider.CreateSerializerSettings())
{
}
@@ -43,32 +38,15 @@ namespace Microsoft.AspNet.Mvc
/// The to be used by
/// the formatter.
public JsonResult(object value, [NotNull] JsonSerializerSettings serializerSettings)
- : this(value, formatter: new JsonOutputFormatter(serializerSettings))
- {
- }
-
- ///
- /// Creates a new with the given .
- ///
- /// The value to format as JSON.
- /// The formatter to use, or null to choose a formatter dynamically.
- public JsonResult(object value, IOutputFormatter formatter)
{
Value = value;
- Formatter = formatter;
-
- ContentTypes = new List();
+ _serializerSettings = serializerSettings;
}
///
- /// Gets or sets the list of supported Content-Types.
+ /// Gets or sets the representing the Content-Type header of the response.
///
- public IList ContentTypes { get; set; }
-
- ///
- /// Gets or sets the formatter.
- ///
- public IOutputFormatter Formatter { get; set; }
+ public MediaTypeHeaderValue ContentType { get; set; }
///
/// Gets or sets the HTTP status code.
@@ -81,80 +59,44 @@ namespace Microsoft.AspNet.Mvc
public object Value { get; set; }
///
- 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.
- // if the user has not already set it.
- if (ContentTypes == null || ContentTypes.Count == 0)
+ var contentTypeHeader = ContentType;
+ if (contentTypeHeader == null)
{
- foreach (var contentType in DefaultContentTypes)
- {
- objectResult.ContentTypes.Add(contentType);
- }
+ contentTypeHeader = DefaultContentType;
}
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()
- {
- 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);
+ response.ContentType = contentTypeHeader.ToString();
if (StatusCode != null)
{
- context.HttpContext.Response.StatusCode = StatusCode.Value;
+ response.StatusCode = StatusCode.Value;
}
- await formatter.WriteAsync(formatterContext);
- }
-
- private IOutputFormatter SelectFormatter(ObjectResult objectResult, OutputFormatterContext formatterContext)
- {
- if (Formatter == null)
+ using (var writer = new HttpResponseStreamWriter(response.Body, contentTypeHeader.Encoding))
{
- // If no formatter was provided, then run Conneg with the formatters configured in options.
- var formatters = formatterContext
- .HttpContext
- .RequestServices
- .GetRequiredService>()
- .Options
- .OutputFormatters
- .OfType()
- .ToArray();
-
- var formatter = objectResult.SelectFormatter(formatterContext, formatters);
- if (formatter == null)
+ using (var jsonWriter = new JsonTextWriter(writer))
{
- // If the available user-configured formatters can't write this type, then fall back to the
- // 'global' one.
- formatter = formatterContext
- .HttpContext
- .RequestServices
- .GetRequiredService();
-
- // Run SelectFormatter again to try to choose a content type that this formatter can do.
- objectResult.SelectFormatter(formatterContext, new[] { formatter });
+ jsonWriter.CloseOutput = false;
+ var jsonSerializer = JsonSerializer.Create(_serializerSettings);
+ jsonSerializer.Serialize(jsonWriter, Value);
}
+ }
- return formatter;
- }
- else
- {
- // Run SelectFormatter to try to choose a content type that this formatter can do.
- objectResult.SelectFormatter(formatterContext, new[] { Formatter });
- return Formatter;
- }
+ return Task.FromResult(true);
}
}
}
diff --git a/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/JsonViewComponentResult.cs b/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/JsonViewComponentResult.cs
index 688a36b917..3a18f9dd27 100644
--- a/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/JsonViewComponentResult.cs
+++ b/src/Microsoft.AspNet.Mvc.Extensions/ViewComponents/JsonViewComponentResult.cs
@@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading.Tasks;
-using Microsoft.Framework.DependencyInjection;
+using Microsoft.AspNet.Mvc.Internal;
using Microsoft.Framework.Internal;
using Newtonsoft.Json;
@@ -13,12 +13,14 @@ namespace Microsoft.AspNet.Mvc
///
public class JsonViewComponentResult : IViewComponentResult
{
+ private readonly JsonSerializerSettings _serializerSettings;
+
///
/// Initializes a new .
///
/// The value to format as JSON text.
public JsonViewComponentResult(object value)
- : this(value, formatter: null)
+ : this(value, serializerSettings: SerializerSettingsProvider.CreateSerializerSettings())
{
}
@@ -29,19 +31,9 @@ namespace Microsoft.AspNet.Mvc
/// The to be used by
/// the formatter.
public JsonViewComponentResult(object value, [NotNull] JsonSerializerSettings serializerSettings)
- : this(value, new JsonOutputFormatter(serializerSettings))
- {
- }
-
- ///
- /// Initializes a new .
- ///
- /// The value to format as JSON text.
- /// The to use.
- public JsonViewComponentResult(object value, JsonOutputFormatter formatter)
{
Value = value;
- Formatter = formatter;
+ _serializerSettings = serializerSettings;
}
///
@@ -49,19 +41,18 @@ namespace Microsoft.AspNet.Mvc
///
public object Value { get; }
- ///
- /// Gets the formatter.
- ///
- public JsonOutputFormatter Formatter { get; }
-
///
/// Renders JSON text to the output.
///
/// The .
public void Execute([NotNull] ViewComponentContext context)
{
- var formatter = Formatter ?? ResolveFormatter(context);
- formatter.WriteObject(context.Writer, Value);
+ using (var jsonWriter = new JsonTextWriter(context.Writer))
+ {
+ jsonWriter.CloseOutput = false;
+ var jsonSerializer = JsonSerializer.Create(_serializerSettings);
+ jsonSerializer.Serialize(jsonWriter, Value);
+ }
}
///
@@ -74,11 +65,5 @@ namespace Microsoft.AspNet.Mvc
Execute(context);
return Task.FromResult(true);
}
-
- private static JsonOutputFormatter ResolveFormatter(ViewComponentContext context)
- {
- var services = context.ViewContext.HttpContext.RequestServices;
- return services.GetRequiredService();
- }
}
}
diff --git a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ApiController.cs b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ApiController.cs
index 29ca1ae261..51ee047790 100644
--- a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ApiController.cs
+++ b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ApiController.cs
@@ -11,6 +11,7 @@ using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.ModelBinding.Validation;
using Microsoft.AspNet.Mvc.WebApiCompatShim;
using Microsoft.Framework.Internal;
+using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;
namespace System.Web.Http
@@ -257,9 +258,7 @@ namespace System.Web.Http
[NonAction]
public virtual JsonResult Json([NotNull] T content, [NotNull] JsonSerializerSettings serializerSettings)
{
- var formatter = new JsonOutputFormatter(serializerSettings);
-
- return new JsonResult(content, formatter);
+ return new JsonResult(content, serializerSettings);
}
///
@@ -276,12 +275,13 @@ namespace System.Web.Http
[NotNull] JsonSerializerSettings serializerSettings,
[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();
- formatter.SupportedEncodings.Add(encoding);
-
- return new JsonResult(content, formatter);
+ return result;
}
///
diff --git a/test/Microsoft.AspNet.Mvc.Extensions.Test/ControllerTests.cs b/test/Microsoft.AspNet.Mvc.Extensions.Test/ControllerTests.cs
index 813647ac56..187f745daf 100644
--- a/test/Microsoft.AspNet.Mvc.Extensions.Test/ControllerTests.cs
+++ b/test/Microsoft.AspNet.Mvc.Extensions.Test/ControllerTests.cs
@@ -1033,7 +1033,7 @@ namespace Microsoft.AspNet.Mvc.Test
}
[Fact]
- public void Controller_Json_WithParameterValueAndSerializerSettings_SetsRespectiveValues()
+ public void Controller_Json_WithParameterValue_SetsRespectiveProperty()
{
// Arrange
var controller = new TestableController();
@@ -1046,8 +1046,6 @@ namespace Microsoft.AspNet.Mvc.Test
// Assert
Assert.IsType(actualJsonResult);
Assert.Same(data, actualJsonResult.Value);
- var jsonFormatter = actualJsonResult.Formatter as JsonOutputFormatter;
- Assert.Same(serializerSettings, jsonFormatter.SerializerSettings);
}
[Fact]
@@ -1094,8 +1092,6 @@ namespace Microsoft.AspNet.Mvc.Test
// Assert
Assert.IsType(result);
Assert.Same(input, result.Value);
- var jsonFormatter = result.Formatter as JsonOutputFormatter;
- Assert.Same(serializerSettings, jsonFormatter.SerializerSettings);
mockHttpContext.Verify(
x => x.Response.OnResponseCompleted(It.IsAny>(), It.IsAny