From a229b20c48a0c379705091982bc36842cb59d47f Mon Sep 17 00:00:00 2001 From: ryanbrandenburg Date: Tue, 12 Jan 2016 16:33:54 -0800 Subject: [PATCH] * StringOutput set proper ContentType --- .../Formatters/StringOutputFormatter.cs | 9 +++- .../Formatters/StringOutputFormatterTests.cs | 48 +++++++++++++++++-- .../ContentNegotiationTest.cs | 24 +++++++++- 3 files changed, 73 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/StringOutputFormatter.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/StringOutputFormatter.cs index 6a8bb81bee..d9b97e45bf 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Formatters/StringOutputFormatter.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/StringOutputFormatter.cs @@ -7,7 +7,6 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Mvc.Internal; using Microsoft.Extensions.Primitives; -using Microsoft.Net.Http.Headers; namespace Microsoft.AspNet.Mvc.Formatters { @@ -34,7 +33,13 @@ namespace Microsoft.AspNet.Mvc.Formatters // always return it as a text/plain format. if (context.ObjectType == typeof(string) || context.Object is string) { - context.ContentType = new StringSegment(SupportedMediaTypes[0]); + if (!context.ContentType.HasValue) + { + var mediaType = SupportedMediaTypes[0]; + var encoding = SupportedEncodings[0]; + context.ContentType = new StringSegment(MediaType.ReplaceEncoding(mediaType, encoding)); + } + return true; } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/StringOutputFormatterTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/StringOutputFormatterTests.cs index 620ac53286..3cfd6da9f2 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/StringOutputFormatterTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/StringOutputFormatterTests.cs @@ -27,6 +27,48 @@ namespace Microsoft.AspNet.Mvc.Formatters } } + [Fact] + public void CanWriteResult_SetsAcceptContentType() + { + // Arrange + var formatter = new StringOutputFormatter(); + var expectedContentType = new StringSegment("application/json"); + + var context = new OutputFormatterWriteContext( + new DefaultHttpContext(), + new TestHttpResponseStreamWriterFactory().CreateWriter, + typeof(string), + "Thisisastring"); + context.ContentType = expectedContentType; + + // Act + var result = formatter.CanWriteResult(context); + + // Assert + Assert.True(result); + Assert.Equal(expectedContentType, context.ContentType); + } + + [Fact] + public void CanWriteResult_DefaultContentType() + { + // Arrange + var formatter = new StringOutputFormatter(); + + var context = new OutputFormatterWriteContext( + new DefaultHttpContext(), + new TestHttpResponseStreamWriterFactory().CreateWriter, + typeof(string), + "Thisisastring"); + + // Act + var result = formatter.CanWriteResult(context); + + // Assert + Assert.True(result); + Assert.Equal(new StringSegment("text/plain; charset=utf-8"), context.ContentType); + } + [Theory] [MemberData(nameof(OutputFormatterContextValues))] public void CanWriteResult_ReturnsTrueForStringTypes( @@ -35,9 +77,7 @@ namespace Microsoft.AspNet.Mvc.Formatters bool expectedCanWriteResult) { // Arrange - var expectedContentType = expectedCanWriteResult ? - new StringSegment("text/plain") : - new StringSegment("application/json"); + var expectedContentType = new StringSegment("application/json"); var formatter = new StringOutputFormatter(); var type = useDeclaredTypeAsString ? typeof(string) : typeof(object); @@ -47,7 +87,7 @@ namespace Microsoft.AspNet.Mvc.Formatters new TestHttpResponseStreamWriterFactory().CreateWriter, type, value); - context.ContentType = new StringSegment("application/json"); + context.ContentType = expectedContentType; // Act var result = formatter.CanWriteResult(context); diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/ContentNegotiationTest.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/ContentNegotiationTest.cs index 2441ab91ea..8280fc9ec5 100644 --- a/test/Microsoft.AspNet.Mvc.FunctionalTests/ContentNegotiationTest.cs +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/ContentNegotiationTest.cs @@ -350,7 +350,27 @@ END:VCARD [Theory] [InlineData(true)] [InlineData(false)] - public async Task ObjectResult_WithStringReturnType_WritesTextPlainFormat(bool matchFormatterOnObjectType) + public async Task ObjectResult_WithStringReturnType_DefaultToTextPlain(bool matchFormatterOnObjectType) + { + // Arrange + var targetUri = "http://localhost/FallbackOnTypeBasedMatch/ReturnString?matchFormatterOnObjectType=true" + + matchFormatterOnObjectType; + var request = new HttpRequestMessage(HttpMethod.Get, targetUri); + + // Act + var response = await Client.SendAsync(request); + + // Assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal("text/plain", response.Content.Headers.ContentType.MediaType); + var actualBody = await response.Content.ReadAsStringAsync(); + Assert.Equal("Hello World!", actualBody); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task ObjectResult_WithStringReturnType_SetsMediaTypeToAccept(bool matchFormatterOnObjectType) { // Arrange var targetUri = "http://localhost/FallbackOnTypeBasedMatch/ReturnString?matchFormatterOnObjectType=" + @@ -363,7 +383,7 @@ END:VCARD // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.Equal("text/plain", response.Content.Headers.ContentType.MediaType); + Assert.Equal("application/json", response.Content.Headers.ContentType.MediaType); var actualBody = await response.Content.ReadAsStringAsync(); Assert.Equal("Hello World!", actualBody); }