// Copyright (c) .NET Foundation. 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.Buffers;
using System.Globalization;
using System.IO;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.Mvc.Rendering;
using Newtonsoft.Json;
namespace Microsoft.AspNetCore.Mvc.ViewFeatures
{
///
/// Default implementation of .
///
public class JsonHelper : IJsonHelper
{
private const string AllowJsonHtml = "Switch.Microsoft.AspNetCore.Mvc.AllowJsonHtml";
private readonly JsonOutputFormatter _jsonOutputFormatter;
private readonly ArrayPool _charPool;
///
/// Initializes a new instance of that is backed by .
///
/// The used to serialize JSON.
///
/// The for use with custom (see
/// ).
///
public JsonHelper(JsonOutputFormatter jsonOutputFormatter, ArrayPool charPool)
{
if (jsonOutputFormatter == null)
{
throw new ArgumentNullException(nameof(jsonOutputFormatter));
}
if (charPool == null)
{
throw new ArgumentNullException(nameof(charPool));
}
_jsonOutputFormatter = jsonOutputFormatter;
_charPool = charPool;
}
///
public IHtmlContent Serialize(object value)
{
if (AppContext.TryGetSwitch(AllowJsonHtml, out var allowJsonHtml) && allowJsonHtml)
{
return SerializeInternal(_jsonOutputFormatter, value);
}
var settings = ShallowCopy(_jsonOutputFormatter.PublicSerializerSettings);
settings.StringEscapeHandling = StringEscapeHandling.EscapeHtml;
return Serialize(value, settings);
}
///
public IHtmlContent Serialize(object value, JsonSerializerSettings serializerSettings)
{
if (serializerSettings == null)
{
throw new ArgumentNullException(nameof(serializerSettings));
}
var jsonOutputFormatter = new JsonOutputFormatter(serializerSettings, _charPool);
return SerializeInternal(jsonOutputFormatter, value);
}
private IHtmlContent SerializeInternal(JsonOutputFormatter jsonOutputFormatter, object value)
{
var stringWriter = new StringWriter(CultureInfo.InvariantCulture);
jsonOutputFormatter.WriteObject(stringWriter, value);
return new HtmlString(stringWriter.ToString());
}
private static JsonSerializerSettings ShallowCopy(JsonSerializerSettings settings)
{
var copiedSettings = new JsonSerializerSettings
{
FloatParseHandling = settings.FloatParseHandling,
FloatFormatHandling = settings.FloatFormatHandling,
DateParseHandling = settings.DateParseHandling,
DateTimeZoneHandling = settings.DateTimeZoneHandling,
DateFormatHandling = settings.DateFormatHandling,
Formatting = settings.Formatting,
MaxDepth = settings.MaxDepth,
DateFormatString = settings.DateFormatString,
Context = settings.Context,
Error = settings.Error,
SerializationBinder = settings.SerializationBinder,
TraceWriter = settings.TraceWriter,
Culture = settings.Culture,
ReferenceResolverProvider = settings.ReferenceResolverProvider,
EqualityComparer = settings.EqualityComparer,
ContractResolver = settings.ContractResolver,
ConstructorHandling = settings.ConstructorHandling,
TypeNameAssemblyFormatHandling = settings.TypeNameAssemblyFormatHandling,
MetadataPropertyHandling = settings.MetadataPropertyHandling,
TypeNameHandling = settings.TypeNameHandling,
PreserveReferencesHandling = settings.PreserveReferencesHandling,
Converters = settings.Converters,
DefaultValueHandling = settings.DefaultValueHandling,
NullValueHandling = settings.NullValueHandling,
ObjectCreationHandling = settings.ObjectCreationHandling,
MissingMemberHandling = settings.MissingMemberHandling,
ReferenceLoopHandling = settings.ReferenceLoopHandling,
CheckAdditionalContent = settings.CheckAdditionalContent,
};
return copiedSettings;
}
}
}