[Fixes #1836]SupportedMediaTypes for output formatters are incorrectly updated with charset data during requests

This commit is contained in:
Kiran Challa 2015-01-19 17:18:12 -08:00 committed by Kiran Challa
parent a2d12669a8
commit eda4b16cc5
5 changed files with 97 additions and 2 deletions

View File

@ -177,6 +177,9 @@ namespace Microsoft.AspNet.Mvc
throw new InvalidOperationException(Resources.FormatOutputFormatterNoMediaType(GetType().FullName));
}
// Clone the media type as we don't want it to affect the next request
selectedMediaType = MediaTypeHeaderValue.Parse(selectedMediaType.ToString());
var selectedEncoding = SelectCharacterEncoding(context);
if (selectedEncoding == null)
{

View File

@ -120,6 +120,29 @@ namespace Microsoft.AspNet.Mvc.Test
formatterContext.SelectedContentType.ToString());
}
[Fact]
public async Task WriteResponseHeaders_ClonesMediaType()
{
// Arrange
var formatter = new PngImageFormatter();
formatter.SupportedMediaTypes.Clear();
var mediaType = new MediaTypeHeaderValue("image/png");
formatter.SupportedMediaTypes.Add(mediaType);
var formatterContext = new OutputFormatterContext();
formatterContext.ActionContext = new ActionContext(
new DefaultHttpContext(),
new RouteData(),
new ActionDescriptor());
// Act
await formatter.WriteAsync(formatterContext);
// Assert
Assert.NotSame(mediaType, formatterContext.SelectedContentType);
Assert.Null(mediaType.Charset);
Assert.Equal("image/png; charset=utf-8", formatterContext.SelectedContentType.ToString());
}
[Fact]
public void CanWriteResult_ForNullContentType_UsesFirstEntryInSupportedContentTypes()
{
@ -294,7 +317,7 @@ namespace Microsoft.AspNet.Mvc.Test
public override bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue contentType)
{
// Do not set the selected media Type.
// The WriteResponseContentHeader should do it for you.
// The WriteResponseHeaders should do it for you.
return true;
}
@ -303,5 +326,19 @@ namespace Microsoft.AspNet.Mvc.Test
return Task.FromResult(true);
}
}
private class PngImageFormatter : OutputFormatter
{
public PngImageFormatter()
{
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("image/png"));
SupportedEncodings.Add(Encoding.UTF8);
}
public override Task WriteResponseBodyAsync([NotNull] OutputFormatterContext context)
{
return Task.FromResult(true);
}
}
}
}

View File

@ -296,6 +296,50 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
Assert.Equal(expectedBody, body);
}
[Fact]
public async Task JsonFormatter_SupportedMediaType_DoesNotChangeAcrossRequests()
{
// Arrange
var server = TestServer.Create(_provider, _app);
var client = server.CreateClient();
var expectedContentType = MediaTypeHeaderValue.Parse("application/json;charset=utf-8");
var expectedBody = "{\"MethodName\":\"ReturnJsonResult\"}";
for (int i = 0; i < 5; i++)
{
// Act and Assert
var response = await client.GetAsync("http://localhost/JsonResult/ReturnJsonResult");
Assert.Equal(expectedContentType, response.Content.Headers.ContentType);
var body = await response.Content.ReadAsStringAsync();
Assert.Equal(expectedBody, body);
}
}
[Fact]
public async Task XmlFormatter_SupportedMediaType_DoesNotChangeAcrossRequests()
{
// Arrange
var server = TestServer.Create(_provider, _app);
var client = server.CreateClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
client.DefaultRequestHeaders.AcceptCharset.Add(new StringWithQualityHeaderValue("utf-8"));
var expectedContentType = MediaTypeHeaderValue.Parse("application/xml;charset=utf-8");
var expectedBody = @"<User xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"" " +
@"xmlns=""http://schemas.datacontract.org/2004/07/ConnegWebSite""><Address>"
+ @"One Microsoft Way</Address><Name>John</Name></User>";
for (int i = 0; i < 5; i++)
{
// Act and Assert
var response = await client.GetAsync("http://localhost/Home/UserInfo");
Assert.Equal(expectedContentType, response.Content.Headers.ContentType);
var body = await response.Content.ReadAsStringAsync();
Assert.Equal(expectedBody, body);
}
}
[Theory]
[InlineData("UseTheFallback_WithDefaultFormatters")]
[InlineData("UseTheFallback_UsingCustomFormatters")]

View File

@ -11,5 +11,10 @@ namespace ConnegWebSite
{
return new JsonResult("Index Method");
}
public User UserInfo()
{
return new User() { Name = "John", Address = "One Microsoft Way" };
}
}
}

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.DependencyInjection;
@ -18,8 +19,13 @@ namespace ConnegWebSite
{
// Add MVC services to the services container
services.AddMvc(configuration);
});
services.Configure<MvcOptions>(options =>
{
options.AddXmlDataContractSerializerFormatter();
});
});
// Add MVC to the request pipeline
app.UseMvc(routes =>
{