diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs index b12bc7f063..47bff12d25 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/JsonResult.cs @@ -4,6 +4,7 @@ using System; using System.IO; using System.Text; +using Microsoft.AspNet.Mvc.Internal; using Newtonsoft.Json; namespace Microsoft.AspNet.Mvc @@ -11,12 +12,10 @@ 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 = UTF8EncodingWithoutBOM; + private Encoding _encoding = UTF8EncodingWithoutBOM.Encoding; public JsonResult(object returnValue) { diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs index d0d1f2bfbd..3ffd50a93b 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs @@ -4,15 +4,16 @@ using System; using System.Collections.Generic; using System.IO; -using System.Text; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.Core; +using Microsoft.AspNet.Mvc.Internal; using Microsoft.AspNet.Mvc.Rendering; namespace Microsoft.AspNet.Mvc { public class ViewResult : ActionResult { + private const int BufferSize = 1024; private readonly IServiceProvider _serviceProvider; private readonly IViewEngine _viewEngine; @@ -35,7 +36,8 @@ namespace Microsoft.AspNet.Mvc { context.HttpContext.Response.ContentType = "text/html; charset=utf-8"; var wrappedStream = new StreamWrapper(context.HttpContext.Response.Body); - using (var writer = new StreamWriter(wrappedStream, new UTF8Encoding(false), 1024, leaveOpen: true)) + var encoding = UTF8EncodingWithoutBOM.Encoding; + using (var writer = new StreamWriter(wrappedStream, encoding, BufferSize, leaveOpen: true)) { try { @@ -81,7 +83,7 @@ namespace Microsoft.AspNet.Mvc _wrappedStream = stream; } - public bool BlockWrites { get; set;} + public bool BlockWrites { get; set; } public override bool CanRead { diff --git a/src/Microsoft.AspNet.Mvc.Core/Internal/UTF8EncodingWithoutBOM.cs b/src/Microsoft.AspNet.Mvc.Core/Internal/UTF8EncodingWithoutBOM.cs new file mode 100644 index 0000000000..3f9df77441 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Internal/UTF8EncodingWithoutBOM.cs @@ -0,0 +1,10 @@ +using System.Text; + +namespace Microsoft.AspNet.Mvc.Internal +{ + public static class UTF8EncodingWithoutBOM + { + public static readonly Encoding Encoding + = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false); + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj b/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj index f6693a7cbb..37cd34b4b7 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj +++ b/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj @@ -133,6 +133,7 @@ + @@ -233,4 +234,4 @@ - + \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj b/test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj index 4bc6c81ae2..54aa5c4496 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj @@ -53,6 +53,7 @@ + \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs new file mode 100644 index 0000000000..5721e49304 --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs @@ -0,0 +1,55 @@ +// 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; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Mvc.Rendering; +using Microsoft.AspNet.Routing; +using Moq; +using Xunit; + +namespace Microsoft.AspNet.Mvc.Core.Test +{ + public class ViewResultTest + { + [Fact] + public async Task ExecuteResultAsync_WritesOutputWithoutBOM() + { + // Arrange + var expected = new byte[] { 97, 98, 99, 100 }; + 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 routeDictionary = new Dictionary(); + var actionContext = new ActionContext(context.Object, + Mock.Of(), + routeDictionary, + new ActionDescriptor()); + var view = new Mock(); + view.Setup(v => v.RenderAsync(It.IsAny())) + .Callback((ViewContext v) => + { + v.Writer.Write("abcd"); + }) + .Returns(Task.FromResult(0)); + var serviceProvider = Mock.Of(); + var viewEngine = new Mock(); + viewEngine.Setup(v => v.FindView(routeDictionary, It.IsAny())) + .Returns(ViewEngineResult.Found("MyView", view.Object)); + var viewResult = new ViewResult(serviceProvider, viewEngine.Object); + + // Act + await viewResult.ExecuteResultAsync(actionContext); + + // Assert + Assert.Equal(expected, memoryStream.ToArray()); + } + } +} \ No newline at end of file