From 6f3511379f31f65d610631550ff07d7dceeda138 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 29 May 2014 15:53:28 -0700 Subject: [PATCH] Modify JsonResult to generate results in UTF8 without BOM by default Fixes #577 --- .../ActionResults/JsonResult.cs | 14 ++-- .../JsonResultTest.cs | 75 +++++++++++++++++++ 2 files changed, 82 insertions(+), 7 deletions(-) create mode 100644 test/Microsoft.AspNet.Mvc.Core.Test/JsonResultTest.cs diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs index 3ae60b1227..b12bc7f063 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs @@ -4,18 +4,19 @@ using System; using System.IO; using System.Text; -using System.Threading.Tasks; -using Microsoft.AspNet.Http; using Newtonsoft.Json; namespace Microsoft.AspNet.Mvc { public class JsonResult : ActionResult { + private const int BufferSize = 1024; + private static readonly Encoding UTF8EncodingWithoutBOM + = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false); private readonly object _returnValue; private JsonSerializerSettings _jsonSerializerSettings; - private Encoding _encoding = Encoding.UTF8; + private Encoding _encoding = UTF8EncodingWithoutBOM; public JsonResult(object returnValue) { @@ -64,16 +65,15 @@ namespace Microsoft.AspNet.Mvc public override void ExecuteResult([NotNull] ActionContext context) { - HttpResponse response = context.HttpContext.Response; - - Stream writeStream = response.Body; + var response = context.HttpContext.Response; + var writeStream = response.Body; if (response.ContentType == null) { response.ContentType = "application/json"; } - using (var writer = new StreamWriter(writeStream, Encoding, 1024, leaveOpen: true)) + using (var writer = new StreamWriter(writeStream, Encoding, BufferSize, leaveOpen: true)) { var formatter = new JsonOutputFormatter(SerializerSettings, Indent); formatter.WriteObject(writer, _returnValue); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/JsonResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/JsonResultTest.cs new file mode 100644 index 0000000000..de3cfe2545 --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.Core.Test/JsonResultTest.cs @@ -0,0 +1,75 @@ +// Copyright (c) Microsoft Open Technologies, Inc. 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.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Routing; +using Moq; +using Xunit; + + +namespace Microsoft.AspNet.Mvc +{ + public class JsonResultTest + { + private static readonly byte[] _abcdUTF8Bytes + = new byte[] { 123, 34, 102, 111, 111, 34, 58, 34, 97, 98, 99, 100, 34, 125 }; + + [Fact] + public async Task ExecuteResult_GeneratesResultsWithoutBOMByDefault() + { + // Arrange + var expected = _abcdUTF8Bytes; + var memoryStream = new MemoryStream(); + var response = new Mock(); + response.SetupGet(r => r.Body) + .Returns(memoryStream); + var context = new Mock(); + context.SetupGet(c => c.Response) + .Returns(response.Object); + var actionContext = new ActionContext(context.Object, + Mock.Of(), + new Dictionary(), + new ActionDescriptor()); + var result = new JsonResult(new { foo = "abcd" }); + + // Act + await result.ExecuteResultAsync(actionContext); + + // Assert + Assert.Equal(expected, memoryStream.ToArray()); + } + + [Fact] + public async Task ExecuteResult_UsesEncoderIfSpecified() + { + // Arrange + var expected = Enumerable.Concat(Encoding.UTF8.GetPreamble(), _abcdUTF8Bytes); + var memoryStream = new MemoryStream(); + var response = new Mock(); + response.SetupGet(r => r.Body) + .Returns(memoryStream); + var context = new Mock(); + context.SetupGet(c => c.Response) + .Returns(response.Object); + var actionContext = new ActionContext(context.Object, + Mock.Of(), + new Dictionary(), + new ActionDescriptor()); + var result = new JsonResult(new { foo = "abcd" }) + { + Encoding = Encoding.UTF8 + }; + + // Act + await result.ExecuteResultAsync(actionContext); + + // Assert + Assert.Equal(expected, memoryStream.ToArray()); + } + } +} \ No newline at end of file