using System;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
using Utf8Json.Internal.Emit;
using Utf8Json.Internal;
using Utf8Json.Formatters;
using System.Text.RegularExpressions;
using System.Threading;
using System.Reflection.Emit;
using Utf8Json.Resolvers.Internal;
namespace Utf8Json.Resolvers
{
///
/// ObjectResolver by dynamic code generation.
///
public static class DynamicObjectResolver
{
/// AllowPrivate:False, ExcludeNull:False, NameMutate:Original
public static readonly IJsonFormatterResolver Default = DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateOriginal.Instance;
/// AllowPrivate:False, ExcludeNull:False, NameMutate:CamelCase
public static readonly IJsonFormatterResolver CamelCase = DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateCamelCase.Instance;
/// AllowPrivate:False, ExcludeNull:False, NameMutate:SnakeCase
public static readonly IJsonFormatterResolver SnakeCase = DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateSnakeCase.Instance;
/// AllowPrivate:False, ExcludeNull:True, NameMutate:Original
public static readonly IJsonFormatterResolver ExcludeNull = DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateOriginal.Instance;
/// AllowPrivate:False, ExcludeNull:True, NameMutate:CamelCase
public static readonly IJsonFormatterResolver ExcludeNullCamelCase = DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateCamelCase.Instance;
/// AllowPrivate:False, ExcludeNull:True, NameMutate:SnakeCase
public static readonly IJsonFormatterResolver ExcludeNullSnakeCase = DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateSnakeCase.Instance;
/// AllowPrivate:True, ExcludeNull:False, NameMutate:Original
public static readonly IJsonFormatterResolver AllowPrivate = DynamicObjectResolverAllowPrivateTrueExcludeNullFalseNameMutateOriginal.Instance;
/// AllowPrivate:True, ExcludeNull:False, NameMutate:CamelCase
public static readonly IJsonFormatterResolver AllowPrivateCamelCase = DynamicObjectResolverAllowPrivateTrueExcludeNullFalseNameMutateCamelCase.Instance;
/// AllowPrivate:True, ExcludeNull:False, NameMutate:SnakeCase
public static readonly IJsonFormatterResolver AllowPrivateSnakeCase = DynamicObjectResolverAllowPrivateTrueExcludeNullFalseNameMutateSnakeCase.Instance;
/// AllowPrivate:True, ExcludeNull:True, NameMutate:Original
public static readonly IJsonFormatterResolver AllowPrivateExcludeNull = DynamicObjectResolverAllowPrivateTrueExcludeNullTrueNameMutateOriginal.Instance;
/// AllowPrivate:True, ExcludeNull:True, NameMutate:CamelCase
public static readonly IJsonFormatterResolver AllowPrivateExcludeNullCamelCase = DynamicObjectResolverAllowPrivateTrueExcludeNullTrueNameMutateCamelCase.Instance;
/// AllowPrivate:True, ExcludeNull:True, NameMutate:SnakeCase
public static readonly IJsonFormatterResolver AllowPrivateExcludeNullSnakeCase = DynamicObjectResolverAllowPrivateTrueExcludeNullTrueNameMutateSnakeCase.Instance;
}
}
namespace Utf8Json.Resolvers.Internal
{
#if DEBUG && (NET45 || NET47)
public interface ISave
{
AssemblyBuilder Save();
}
#endif
#region DynamicAssembly
internal sealed class DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateOriginal : IJsonFormatterResolver
#if DEBUG && (NET45 || NET47)
, ISave
#endif
{
// configuration
public static readonly IJsonFormatterResolver Instance = new DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateOriginal();
static readonly Func nameMutator = StringMutator.Original;
static readonly bool excludeNull = false;
const string ModuleName = "Utf8Json.Resolvers.DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateOriginal";
static readonly DynamicAssembly assembly;
static DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateOriginal()
{
assembly = new DynamicAssembly(ModuleName);
}
DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateOriginal()
{
}
#if DEBUG && (NET45 || NET47)
public AssemblyBuilder Save()
{
return assembly.Save();
}
#endif
public IJsonFormatter GetFormatter()
{
return FormatterCache.formatter;
}
static class FormatterCache
{
public static readonly IJsonFormatter formatter;
static FormatterCache()
{
formatter = (IJsonFormatter)DynamicObjectTypeBuilder.BuildFormatterToAssembly(assembly, Instance, nameMutator, excludeNull);
}
}
}
internal sealed class DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateCamelCase : IJsonFormatterResolver
#if DEBUG && (NET45 || NET47)
, ISave
#endif
{
// configuration
public static readonly IJsonFormatterResolver Instance = new DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateCamelCase();
static readonly Func nameMutator = StringMutator.ToCamelCase;
static readonly bool excludeNull = false;
const string ModuleName = "Utf8Json.Resolvers.DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateCamelCase";
static readonly DynamicAssembly assembly;
static DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateCamelCase()
{
assembly = new DynamicAssembly(ModuleName);
}
DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateCamelCase()
{
}
#if DEBUG && (NET45 || NET47)
public AssemblyBuilder Save()
{
return assembly.Save();
}
#endif
public IJsonFormatter GetFormatter()
{
return FormatterCache.formatter;
}
static class FormatterCache
{
public static readonly IJsonFormatter formatter;
static FormatterCache()
{
formatter = (IJsonFormatter)DynamicObjectTypeBuilder.BuildFormatterToAssembly(assembly, Instance, nameMutator, excludeNull);
}
}
}
internal sealed class DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateSnakeCase : IJsonFormatterResolver
#if DEBUG && (NET45 || NET47)
, ISave
#endif
{
// configuration
public static readonly IJsonFormatterResolver Instance = new DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateSnakeCase();
static readonly Func nameMutator = StringMutator.ToSnakeCase;
static readonly bool excludeNull = false;
const string ModuleName = "Utf8Json.Resolvers.DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateSnakeCase";
static readonly DynamicAssembly assembly;
static DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateSnakeCase()
{
assembly = new DynamicAssembly(ModuleName);
}
DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateSnakeCase()
{
}
#if DEBUG && (NET45 || NET47)
public AssemblyBuilder Save()
{
return assembly.Save();
}
#endif
public IJsonFormatter GetFormatter()
{
return FormatterCache.formatter;
}
static class FormatterCache
{
public static readonly IJsonFormatter formatter;
static FormatterCache()
{
formatter = (IJsonFormatter)DynamicObjectTypeBuilder.BuildFormatterToAssembly(assembly, Instance, nameMutator, excludeNull);
}
}
}
internal sealed class DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateOriginal : IJsonFormatterResolver
#if DEBUG && (NET45 || NET47)
, ISave
#endif
{
// configuration
public static readonly IJsonFormatterResolver Instance = new DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateOriginal();
static readonly Func nameMutator = StringMutator.Original;
static readonly bool excludeNull = true;
const string ModuleName = "Utf8Json.Resolvers.DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateOriginal";
static readonly DynamicAssembly assembly;
static DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateOriginal()
{
assembly = new DynamicAssembly(ModuleName);
}
DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateOriginal()
{
}
#if DEBUG && (NET45 || NET47)
public AssemblyBuilder Save()
{
return assembly.Save();
}
#endif
public IJsonFormatter GetFormatter()
{
return FormatterCache.formatter;
}
static class FormatterCache
{
public static readonly IJsonFormatter formatter;
static FormatterCache()
{
formatter = (IJsonFormatter)DynamicObjectTypeBuilder.BuildFormatterToAssembly(assembly, Instance, nameMutator, excludeNull);
}
}
}
internal sealed class DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateCamelCase : IJsonFormatterResolver
#if DEBUG && (NET45 || NET47)
, ISave
#endif
{
// configuration
public static readonly IJsonFormatterResolver Instance = new DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateCamelCase();
static readonly Func nameMutator = StringMutator.ToCamelCase;
static readonly bool excludeNull = true;
const string ModuleName = "Utf8Json.Resolvers.DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateCamelCase";
static readonly DynamicAssembly assembly;
static DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateCamelCase()
{
assembly = new DynamicAssembly(ModuleName);
}
DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateCamelCase()
{
}
#if DEBUG && (NET45 || NET47)
public AssemblyBuilder Save()
{
return assembly.Save();
}
#endif
public IJsonFormatter GetFormatter()
{
return FormatterCache.formatter;
}
static class FormatterCache
{
public static readonly IJsonFormatter formatter;
static FormatterCache()
{
formatter = (IJsonFormatter)DynamicObjectTypeBuilder.BuildFormatterToAssembly(assembly, Instance, nameMutator, excludeNull);
}
}
}
internal sealed class DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateSnakeCase : IJsonFormatterResolver
#if DEBUG && (NET45 || NET47)
, ISave
#endif
{
// configuration
public static readonly IJsonFormatterResolver Instance = new DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateSnakeCase();
static readonly Func nameMutator = StringMutator.ToSnakeCase;
static readonly bool excludeNull = true;
const string ModuleName = "Utf8Json.Resolvers.DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateSnakeCase";
static readonly DynamicAssembly assembly;
static DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateSnakeCase()
{
assembly = new DynamicAssembly(ModuleName);
}
DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateSnakeCase()
{
}
#if DEBUG && (NET45 || NET47)
public AssemblyBuilder Save()
{
return assembly.Save();
}
#endif
public IJsonFormatter GetFormatter()
{
return FormatterCache.formatter;
}
static class FormatterCache
{
public static readonly IJsonFormatter formatter;
static FormatterCache()
{
formatter = (IJsonFormatter)DynamicObjectTypeBuilder.BuildFormatterToAssembly(assembly, Instance, nameMutator, excludeNull);
}
}
}
#endregion
#region DynamicMethod
internal sealed class DynamicObjectResolverAllowPrivateTrueExcludeNullFalseNameMutateOriginal : IJsonFormatterResolver
{
// configuration
public static readonly IJsonFormatterResolver Instance = new DynamicObjectResolverAllowPrivateTrueExcludeNullFalseNameMutateOriginal();
static readonly Func nameMutator = StringMutator.Original;
static readonly bool excludeNull = false;
public IJsonFormatter GetFormatter()
{
return FormatterCache.formatter;
}
static class FormatterCache
{
public static readonly IJsonFormatter formatter;
static FormatterCache()
{
formatter = (IJsonFormatter)DynamicObjectTypeBuilder.BuildFormatterToDynamicMethod(Instance, nameMutator, excludeNull, true);
}
}
}
internal sealed class DynamicObjectResolverAllowPrivateTrueExcludeNullFalseNameMutateCamelCase : IJsonFormatterResolver
{
// configuration
public static readonly IJsonFormatterResolver Instance = new DynamicObjectResolverAllowPrivateTrueExcludeNullFalseNameMutateCamelCase();
static readonly Func nameMutator = StringMutator.ToCamelCase;
static readonly bool excludeNull = false;
public IJsonFormatter GetFormatter()
{
return FormatterCache.formatter;
}
static class FormatterCache
{
public static readonly IJsonFormatter formatter;
static FormatterCache()
{
formatter = (IJsonFormatter)DynamicObjectTypeBuilder.BuildFormatterToDynamicMethod(Instance, nameMutator, excludeNull, true);
}
}
}
internal sealed class DynamicObjectResolverAllowPrivateTrueExcludeNullFalseNameMutateSnakeCase : IJsonFormatterResolver
{
// configuration
public static readonly IJsonFormatterResolver Instance = new DynamicObjectResolverAllowPrivateTrueExcludeNullFalseNameMutateSnakeCase();
static readonly Func nameMutator = StringMutator.ToSnakeCase;
static readonly bool excludeNull = false;
public IJsonFormatter GetFormatter()
{
return FormatterCache.formatter;
}
static class FormatterCache
{
public static readonly IJsonFormatter formatter;
static FormatterCache()
{
formatter = (IJsonFormatter)DynamicObjectTypeBuilder.BuildFormatterToDynamicMethod(Instance, nameMutator, excludeNull, true);
}
}
}
internal sealed class DynamicObjectResolverAllowPrivateTrueExcludeNullTrueNameMutateOriginal : IJsonFormatterResolver
{
// configuration
public static readonly IJsonFormatterResolver Instance = new DynamicObjectResolverAllowPrivateTrueExcludeNullTrueNameMutateOriginal();
static readonly Func nameMutator = StringMutator.Original;
static readonly bool excludeNull = true;
public IJsonFormatter GetFormatter()
{
return FormatterCache.formatter;
}
static class FormatterCache
{
public static readonly IJsonFormatter formatter;
static FormatterCache()
{
formatter = (IJsonFormatter)DynamicObjectTypeBuilder.BuildFormatterToDynamicMethod(Instance, nameMutator, excludeNull, true);
}
}
}
internal sealed class DynamicObjectResolverAllowPrivateTrueExcludeNullTrueNameMutateCamelCase : IJsonFormatterResolver
{
// configuration
public static readonly IJsonFormatterResolver Instance = new DynamicObjectResolverAllowPrivateTrueExcludeNullTrueNameMutateCamelCase();
static readonly Func nameMutator = StringMutator.ToCamelCase;
static readonly bool excludeNull = true;
public IJsonFormatter GetFormatter()
{
return FormatterCache.formatter;
}
static class FormatterCache
{
public static readonly IJsonFormatter formatter;
static FormatterCache()
{
formatter = (IJsonFormatter)DynamicObjectTypeBuilder.BuildFormatterToDynamicMethod(Instance, nameMutator, excludeNull, true);
}
}
}
internal sealed class DynamicObjectResolverAllowPrivateTrueExcludeNullTrueNameMutateSnakeCase : IJsonFormatterResolver
{
// configuration
public static readonly IJsonFormatterResolver Instance = new DynamicObjectResolverAllowPrivateTrueExcludeNullTrueNameMutateSnakeCase();
static readonly Func nameMutator = StringMutator.ToSnakeCase;
static readonly bool excludeNull = true;
public IJsonFormatter GetFormatter()
{
return FormatterCache.formatter;
}
static class FormatterCache
{
public static readonly IJsonFormatter formatter;
static FormatterCache()
{
formatter = (IJsonFormatter)DynamicObjectTypeBuilder.BuildFormatterToDynamicMethod(Instance, nameMutator, excludeNull, true);
}
}
}
#endregion
internal static class DynamicObjectTypeBuilder
{
#if NETSTANDARD
static readonly Regex SubtractFullNameRegex = new Regex(@", Version=\d+.\d+.\d+.\d+, Culture=\w+, PublicKeyToken=\w+", RegexOptions.Compiled);
#else
static readonly Regex SubtractFullNameRegex = new Regex(@", Version=\d+.\d+.\d+.\d+, Culture=\w+, PublicKeyToken=\w+");
#endif
static int nameSequence = 0;
static HashSet ignoreTypes = new HashSet
{
{typeof(object)},
{typeof(short)},
{typeof(int)},
{typeof(long)},
{typeof(ushort)},
{typeof(uint)},
{typeof(ulong)},
{typeof(float)},
{typeof(double)},
{typeof(bool)},
{typeof(byte)},
{typeof(sbyte)},
{typeof(decimal)},
{typeof(char)},
{typeof(string)},
{typeof(System.Guid)},
{typeof(System.TimeSpan)},
{typeof(System.DateTime)},
{typeof(System.DateTimeOffset)},
};
static HashSet jsonPrimitiveTypes = new HashSet
{
{typeof(short)},
{typeof(int)},
{typeof(long)},
{typeof(ushort)},
{typeof(uint)},
{typeof(ulong)},
{typeof(float)},
{typeof(double)},
{typeof(bool)},
{typeof(byte)},
{typeof(sbyte)},
{typeof(string)},
};
public static object BuildFormatterToAssembly(DynamicAssembly assembly, IJsonFormatterResolver selfResolver, Func nameMutator, bool excludeNull)
{
var ti = typeof(T).GetTypeInfo();
if (ti.IsNullable())
{
ti = ti.GenericTypeArguments[0].GetTypeInfo();
var innerFormatter = selfResolver.GetFormatterDynamic(ti.AsType());
if (innerFormatter == null)
{
return null;
}
return (IJsonFormatter)Activator.CreateInstance(typeof(StaticNullableFormatter<>).MakeGenericType(ti.AsType()), new object[] { innerFormatter });
}
Type elementType;
if (typeof(Exception).GetTypeInfo().IsAssignableFrom(ti))
{
return DynamicObjectTypeBuilder.BuildAnonymousFormatter(typeof(T), nameMutator, excludeNull, false, true);
}
else if (ti.IsAnonymous() || TryGetInterfaceEnumerableElementType(typeof(T), out elementType))
{
return DynamicObjectTypeBuilder.BuildAnonymousFormatter(typeof(T), nameMutator, excludeNull, false, false);
}
var formatterTypeInfo = DynamicObjectTypeBuilder.BuildType(assembly, typeof(T), nameMutator, excludeNull);
if (formatterTypeInfo == null) return null;
return (IJsonFormatter)Activator.CreateInstance(formatterTypeInfo.AsType());
}
public static object BuildFormatterToDynamicMethod(IJsonFormatterResolver selfResolver, Func nameMutator, bool excludeNull, bool allowPrivate)
{
var ti = typeof(T).GetTypeInfo();
if (ti.IsNullable())
{
ti = ti.GenericTypeArguments[0].GetTypeInfo();
var innerFormatter = selfResolver.GetFormatterDynamic(ti.AsType());
if (innerFormatter == null)
{
return null;
}
return (IJsonFormatter)Activator.CreateInstance(typeof(StaticNullableFormatter<>).MakeGenericType(ti.AsType()), new object[] { innerFormatter });
}
if (typeof(Exception).GetTypeInfo().IsAssignableFrom(ti))
{
return DynamicObjectTypeBuilder.BuildAnonymousFormatter(typeof(T), nameMutator, excludeNull, false, true);
}
else
{
return DynamicObjectTypeBuilder.BuildAnonymousFormatter(typeof(T), nameMutator, excludeNull, allowPrivate, false);
}
}
static TypeInfo BuildType(DynamicAssembly assembly, Type type, Func nameMutator, bool excludeNull)
{
if (ignoreTypes.Contains(type)) return null;
var serializationInfo = new MetaType(type, nameMutator, false); // allowPrivate:false
var hasShouldSerialize = serializationInfo.Members.Any(x => x.ShouldSerializeMethodInfo != null);
var formatterType = typeof(IJsonFormatter<>).MakeGenericType(type);
var typeBuilder = assembly.DefineType("Utf8Json.Formatters." + SubtractFullNameRegex.Replace(type.FullName, "").Replace(".", "_") + "Formatter" + Interlocked.Increment(ref nameSequence), TypeAttributes.Public | TypeAttributes.Sealed, null, new[] { formatterType });
FieldBuilder stringByteKeysField;
Dictionary customFormatterLookup;
// for serialize, bake cache.
{
var method = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
stringByteKeysField = typeBuilder.DefineField("stringByteKeys", typeof(byte[][]), FieldAttributes.Private | FieldAttributes.InitOnly);
var il = method.GetILGenerator();
customFormatterLookup = BuildConstructor(typeBuilder, serializationInfo, method, stringByteKeysField, il, excludeNull, hasShouldSerialize);
}
{
var method = typeBuilder.DefineMethod("Serialize", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual,
null,
new Type[] { typeof(JsonWriter).MakeByRefType(), type, typeof(IJsonFormatterResolver) });
var il = method.GetILGenerator();
BuildSerialize(type, serializationInfo, il, () =>
{
il.EmitLoadThis();
il.EmitLdfld(stringByteKeysField);
}, (index, member) =>
{
FieldInfo fi;
if (!customFormatterLookup.TryGetValue(member, out fi)) return false;
il.EmitLoadThis();
il.EmitLdfld(fi);
return true;
}, excludeNull, hasShouldSerialize, 1); // firstArgIndex:0 is this.
}
{
var method = typeBuilder.DefineMethod("Deserialize", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual,
type,
new Type[] { typeof(JsonReader).MakeByRefType(), typeof(IJsonFormatterResolver) });
var il = method.GetILGenerator();
BuildDeserialize(type, serializationInfo, il, (index, member) =>
{
FieldInfo fi;
if (!customFormatterLookup.TryGetValue(member, out fi)) return false;
il.EmitLoadThis();
il.EmitLdfld(fi);
return true;
}, false, 1); // firstArgIndex:0 is this.
}
return typeBuilder.CreateTypeInfo();
}
public static object BuildAnonymousFormatter(Type type, Func nameMutator, bool excludeNull, bool allowPrivate, bool isException)
{
if (ignoreTypes.Contains(type)) return false;
MetaType serializationInfo;
if (isException)
{
var ignoreSet = new HashSet(new[]
{
"HelpLink", "TargetSite", "HResult", "Data", "ClassName", "InnerException"
}.Select(x => nameMutator(x)));
// special case for exception, modify
serializationInfo = new MetaType(type, nameMutator, false);
serializationInfo.BestmatchConstructor = null;
serializationInfo.ConstructorParameters = new MetaMember[0];
serializationInfo.Members = new[] { new StringConstantValueMetaMember(nameMutator("ClassName"), type.FullName) }
.Concat(serializationInfo.Members.Where(x => !ignoreSet.Contains(x.Name)))
.Concat(new[] { new InnerExceptionMetaMember(nameMutator("InnerException")) })
.ToArray();
}
else
{
serializationInfo = new MetaType(type, nameMutator, allowPrivate); // can be allowPrivate:true
}
var hasShouldSerialize = serializationInfo.Members.Any(x => x.ShouldSerializeMethodInfo != null);
// build instance instead of emit constructor.
List stringByteKeysField = new List();
var i = 0;
foreach (var item in serializationInfo.Members.Where(x => x.IsReadable))
{
if (excludeNull || hasShouldSerialize)
{
stringByteKeysField.Add(JsonWriter.GetEncodedPropertyName(item.Name));
}
else
{
if (i == 0)
{
stringByteKeysField.Add(JsonWriter.GetEncodedPropertyNameWithBeginObject(item.Name));
}
else
{
stringByteKeysField.Add(JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator(item.Name));
}
}
i++;
}
List