diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs index 2b850b0f8e..0144bcc791 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs @@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Mvc } _returnValue = returnValue; - _jsonSerializerSettings = CreateSerializerSettings(); + _jsonSerializerSettings = JsonOutputFormatter.CreateDefaultSettings(); } public JsonSerializerSettings SerializerSettings @@ -70,45 +70,11 @@ namespace Microsoft.AspNet.Mvc response.ContentType = "application/json"; } - using (JsonWriter jsonWriter = CreateJsonWriter(writeStream, Encoding)) + using (var writer = new StreamWriter(writeStream, Encoding, 1024, leaveOpen: true)) { - jsonWriter.CloseOutput = false; - - JsonSerializer jsonSerializer = CreateJsonSerializer(); - jsonSerializer.Serialize(jsonWriter, _returnValue); - - jsonWriter.Flush(); + var formatter = new JsonOutputFormatter(SerializerSettings, Indent); + formatter.WriteObject(writer, _returnValue); } } - - private JsonSerializerSettings CreateSerializerSettings() - { - return new JsonSerializerSettings() - { - MissingMemberHandling = MissingMemberHandling.Ignore, - - // Do not change this setting - // Setting this to None prevents Json.NET from loading malicious, unsafe, or security-sensitive types. - TypeNameHandling = TypeNameHandling.None - }; - } - - private JsonSerializer CreateJsonSerializer() - { - JsonSerializer jsonSerializer = JsonSerializer.Create(SerializerSettings); - - return jsonSerializer; - } - - private JsonWriter CreateJsonWriter(Stream writeStream, Encoding effectiveEncoding) - { - JsonWriter jsonWriter = new JsonTextWriter(new StreamWriter(writeStream, effectiveEncoding)); - if (Indent) - { - jsonWriter.Formatting = Formatting.Indented; - } - - return jsonWriter; - } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/JsonOutputFormatter.cs b/src/Microsoft.AspNet.Mvc.Core/JsonOutputFormatter.cs new file mode 100644 index 0000000000..c1640b32a6 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/JsonOutputFormatter.cs @@ -0,0 +1,63 @@ + +using System.IO; +using Newtonsoft.Json; + +namespace Microsoft.AspNet.Mvc +{ + public class JsonOutputFormatter + { + private readonly JsonSerializerSettings _settings; + private readonly bool _indent; + + public JsonOutputFormatter([NotNull] JsonSerializerSettings settings, bool indent) + { + _settings = settings; + _indent = indent; + } + + public static JsonSerializerSettings CreateDefaultSettings() + { + return new JsonSerializerSettings() + { + MissingMemberHandling = MissingMemberHandling.Ignore, + + // Do not change this setting + // Setting this to None prevents Json.NET from loading malicious, unsafe, or security-sensitive types. + TypeNameHandling = TypeNameHandling.None + }; + } + + public void WriteObject([NotNull] TextWriter writer, object value) + { + using (var jsonWriter = CreateJsonWriter(writer)) + { + var jsonSerializer = CreateJsonSerializer(); + jsonSerializer.Serialize(jsonWriter, value); + + // We're explicitly calling flush here to simplify the debugging experience because the + // underlying TextWriter might be long-lived. If this method ends up being called repeatedly + // for a request, we should revisit. + jsonWriter.Flush(); + } + } + + private JsonWriter CreateJsonWriter([NotNull] TextWriter writer) + { + var jsonWriter = new JsonTextWriter(writer); + if (_indent) + { + jsonWriter.Formatting = Formatting.Indented; + } + + jsonWriter.CloseOutput = false; + + return jsonWriter; + } + + private JsonSerializer CreateJsonSerializer() + { + var jsonSerializer = JsonSerializer.Create(_settings); + return jsonSerializer; + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/JsonViewComponentResult.cs b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/JsonViewComponentResult.cs index 122d9d7890..bca820f900 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/JsonViewComponentResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/JsonViewComponentResult.cs @@ -1,6 +1,5 @@  using System; -using System.IO; using System.Threading.Tasks; using Newtonsoft.Json; @@ -15,7 +14,7 @@ namespace Microsoft.AspNet.Mvc public JsonViewComponentResult([NotNull] object value) { _value = value; - _jsonSerializerSettings = CreateSerializerSettings(); + _jsonSerializerSettings = JsonOutputFormatter.CreateDefaultSettings(); } public JsonSerializerSettings SerializerSettings @@ -38,46 +37,10 @@ namespace Microsoft.AspNet.Mvc /// public bool Indent { get; set; } - private JsonSerializerSettings CreateSerializerSettings() - { - return new JsonSerializerSettings() - { - MissingMemberHandling = MissingMemberHandling.Ignore, - - // Do not change this setting - // Setting this to None prevents Json.NET from loading malicious, unsafe, or security-sensitive types. - TypeNameHandling = TypeNameHandling.None - }; - } - - private JsonSerializer CreateJsonSerializer() - { - var jsonSerializer = JsonSerializer.Create(SerializerSettings); - return jsonSerializer; - } - - private JsonWriter CreateJsonWriter([NotNull] TextWriter writer) - { - var jsonWriter = new JsonTextWriter(writer); - if (Indent) - { - jsonWriter.Formatting = Formatting.Indented; - } - - return jsonWriter; - } - public void Execute([NotNull] ViewComponentContext context) { - using (var jsonWriter = CreateJsonWriter(context.Writer)) - { - jsonWriter.CloseOutput = false; - - var jsonSerializer = CreateJsonSerializer(); - jsonSerializer.Serialize(jsonWriter, _value); - - jsonWriter.Flush(); - } + var formatter = new JsonOutputFormatter(SerializerSettings, Indent); + formatter.WriteObject(context.Writer, _value); } public async Task ExecuteAsync([NotNull] ViewComponentContext context)