Modify JsonResult to generate results in UTF8 without BOM by default

Fixes #577
This commit is contained in:
Pranav K 2014-05-29 15:53:28 -07:00
parent 1284ab63b6
commit 6f3511379f
2 changed files with 82 additions and 7 deletions

View File

@ -4,18 +4,19 @@
using System; using System;
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
{ {
public class JsonResult : ActionResult public class JsonResult : ActionResult
{ {
private const int BufferSize = 1024;
private static readonly Encoding UTF8EncodingWithoutBOM
= new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
private readonly object _returnValue; private readonly object _returnValue;
private JsonSerializerSettings _jsonSerializerSettings; private JsonSerializerSettings _jsonSerializerSettings;
private Encoding _encoding = Encoding.UTF8; private Encoding _encoding = UTF8EncodingWithoutBOM;
public JsonResult(object returnValue) public JsonResult(object returnValue)
{ {
@ -64,16 +65,15 @@ namespace Microsoft.AspNet.Mvc
public override void ExecuteResult([NotNull] ActionContext context) public override void ExecuteResult([NotNull] ActionContext context)
{ {
HttpResponse response = context.HttpContext.Response; var response = context.HttpContext.Response;
var writeStream = response.Body;
Stream writeStream = response.Body;
if (response.ContentType == null) if (response.ContentType == null)
{ {
response.ContentType = "application/json"; 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); var formatter = new JsonOutputFormatter(SerializerSettings, Indent);
formatter.WriteObject(writer, _returnValue); formatter.WriteObject(writer, _returnValue);

View File

@ -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<HttpResponse>();
response.SetupGet(r => r.Body)
.Returns(memoryStream);
var context = new Mock<HttpContext>();
context.SetupGet(c => c.Response)
.Returns(response.Object);
var actionContext = new ActionContext(context.Object,
Mock.Of<IRouter>(),
new Dictionary<string, object>(),
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<HttpResponse>();
response.SetupGet(r => r.Body)
.Returns(memoryStream);
var context = new Mock<HttpContext>();
context.SetupGet(c => c.Response)
.Returns(response.Object);
var actionContext = new ActionContext(context.Object,
Mock.Of<IRouter>(),
new Dictionary<string, object>(),
new ActionDescriptor());
var result = new JsonResult(new { foo = "abcd" })
{
Encoding = Encoding.UTF8
};
// Act
await result.ExecuteResultAsync(actionContext);
// Assert
Assert.Equal(expected, memoryStream.ToArray());
}
}
}