Pool JsonSerializer for Output formatting
This commit is contained in:
parent
ccfd235f50
commit
e75eebbed0
|
|
@ -17,6 +17,10 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
{
|
||||
private JsonSerializerSettings _serializerSettings;
|
||||
|
||||
// Perf: JsonSerializers are relatively expensive to create, and are thread safe. We cache
|
||||
// the serializer and invalidate it when the settings change.
|
||||
private JsonSerializer _serializer;
|
||||
|
||||
public JsonOutputFormatter()
|
||||
: this(SerializerSettingsProvider.CreateSerializerSettings())
|
||||
{
|
||||
|
|
@ -40,6 +44,10 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
/// <summary>
|
||||
/// Gets or sets the <see cref="JsonSerializerSettings"/> used to configure the <see cref="JsonSerializer"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Any modifications to the <see cref="JsonSerializerSettings"/> object after this
|
||||
/// <see cref="JsonOutputFormatter"/> has been used will have no effect.
|
||||
/// </remarks>
|
||||
public JsonSerializerSettings SerializerSettings
|
||||
{
|
||||
get
|
||||
|
|
@ -54,6 +62,9 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
}
|
||||
|
||||
_serializerSettings = value;
|
||||
|
||||
// If the settings change, then invalidate the cached serializer.
|
||||
_serializer = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -95,7 +106,12 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
/// <returns>The <see cref="JsonSerializer"/> used during serialization and deserialization.</returns>
|
||||
protected virtual JsonSerializer CreateJsonSerializer()
|
||||
{
|
||||
return JsonSerializer.Create(SerializerSettings);
|
||||
if (_serializer == null)
|
||||
{
|
||||
_serializer = JsonSerializer.Create(SerializerSettings);
|
||||
}
|
||||
|
||||
return _serializer;
|
||||
}
|
||||
|
||||
public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Http.Internal;
|
||||
using Microsoft.AspNet.Mvc.Abstractions;
|
||||
using Microsoft.AspNet.Mvc.Internal;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.AspNet.Testing;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
|
@ -74,6 +75,79 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
Assert.Equal(expectedOutput, content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ChangesTo_DefaultSerializerSettings_AfterSerialization_NoEffect()
|
||||
{
|
||||
// Arrange
|
||||
var person = new User() { Name = "John", Age = 35 };
|
||||
var expectedOutput = JsonConvert.SerializeObject(
|
||||
person,
|
||||
SerializerSettingsProvider.CreateSerializerSettings());
|
||||
|
||||
var jsonFormatter = new JsonOutputFormatter();
|
||||
|
||||
// This will create a serializer - which gets cached.
|
||||
var outputFormatterContext1 = GetOutputFormatterContext(person, typeof(User));
|
||||
await jsonFormatter.WriteResponseBodyAsync(outputFormatterContext1);
|
||||
|
||||
// These changes should have no effect.
|
||||
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
|
||||
jsonFormatter.SerializerSettings.Formatting = Formatting.Indented;
|
||||
|
||||
var outputFormatterContext2 = GetOutputFormatterContext(person, typeof(User));
|
||||
|
||||
// Act
|
||||
await jsonFormatter.WriteResponseBodyAsync(outputFormatterContext2);
|
||||
|
||||
// Assert
|
||||
var body = outputFormatterContext2.HttpContext.Response.Body;
|
||||
|
||||
Assert.NotNull(body);
|
||||
body.Position = 0;
|
||||
|
||||
var content = new StreamReader(body, Encoding.UTF8).ReadToEnd();
|
||||
Assert.Equal(expectedOutput, content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReplaceSerializerSettings_AfterSerialization_TakesEffect()
|
||||
{
|
||||
// Arrange
|
||||
var person = new User() { Name = "John", Age = 35 };
|
||||
var expectedOutput = JsonConvert.SerializeObject(person, new JsonSerializerSettings()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
Formatting = Formatting.Indented
|
||||
});
|
||||
|
||||
var jsonFormatter = new JsonOutputFormatter();
|
||||
|
||||
// This will create a serializer - which gets cached.
|
||||
var outputFormatterContext1 = GetOutputFormatterContext(person, typeof(User));
|
||||
await jsonFormatter.WriteResponseBodyAsync(outputFormatterContext1);
|
||||
|
||||
// This results in a new serializer being created.
|
||||
jsonFormatter.SerializerSettings = new JsonSerializerSettings()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
Formatting = Formatting.Indented,
|
||||
};
|
||||
|
||||
var outputFormatterContext2 = GetOutputFormatterContext(person, typeof(User));
|
||||
|
||||
// Act
|
||||
await jsonFormatter.WriteResponseBodyAsync(outputFormatterContext2);
|
||||
|
||||
// Assert
|
||||
var body = outputFormatterContext2.HttpContext.Response.Body;
|
||||
|
||||
Assert.NotNull(body);
|
||||
body.Position = 0;
|
||||
|
||||
var content = new StreamReader(body, Encoding.UTF8).ReadToEnd();
|
||||
Assert.Equal(expectedOutput, content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CustomSerializerSettingsObject_TakesEffect()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue