<value>The specified type {0} must derive from the specific value's type {1}.</value>
</data>
<data name="SerializationInvalidBufferSize" xml:space="preserve">
- <value>The value must be greater than zero or equal to -1.</value>
+ <value>The value must be greater than zero.</value>
</data>
<data name="BufferWriterAdvancedTooFar" xml:space="preserve">
<value>Cannot advance past the end of the buffer, which has a size of {0}.</value>
</data>
- <data name="EnumConverterNotImplemented" xml:space="preserve">
- <value>EnumConverter is not yet supported on .NET Standard 2.0.</value>
- </data>
<data name="InvalidComparison" xml:space="preserve">
<value>Cannot compare the value of a token type '{0}' to text.</value>
</data>
<data name="FormatDateTimeOffset" xml:space="preserve">
<value>The JSON value is of unsupported format for a DateTimeOffset.</value>
</data>
-</root>
+</root>
\ No newline at end of file
{
public static partial class JsonSerializer
{
+ /// <summary>
+ /// Parse the UTF-8 encoded text representing a single JSON value into a <typeparamref name="TValue"/>.
+ /// </summary>
+ /// <returns>A <typeparamref name="TValue"/> representation of the JSON value.</returns>
+ /// <param name="utf8Json">JSON text to parse.</param>
+ /// <param name="options">Options to control the behavior during parsing.</param>
+ /// <exception cref="JsonReaderException">
+ /// Thrown when the JSON is invalid,
+ /// <typeparamref name="TValue"/> is not compatible with the JSON,
+ /// or when there is remaining data in the Stream.
+ /// </exception>
public static TValue Parse<TValue>(ReadOnlySpan<byte> utf8Json, JsonSerializerOptions options = null)
{
- if (utf8Json == null)
- throw new ArgumentNullException(nameof(utf8Json));
-
return (TValue)ParseCore(utf8Json, typeof(TValue), options);
}
+ /// <summary>
+ /// Parse the UTF-8 encoded text representing a single JSON value into a <paramref name="returnType"/>.
+ /// </summary>
+ /// <returns>A <paramref name="returnType"/> representation of the JSON value.</returns>
+ /// <param name="utf8Json">JSON text to parse.</param>
+ /// <param name="returnType">The type of the object to convert to and return.</param>
+ /// <param name="options">Options to control the behavior during parsing.</param>
+ /// <exception cref="System.ArgumentNullException">
+ /// Thrown if <paramref name="returnType"/> is null.
+ /// </exception>
+ /// <exception cref="JsonReaderException">
+ /// Thrown when the JSON is invalid,
+ /// <paramref name="returnType"/> is not compatible with the JSON,
+ /// or when there is remaining data in the Stream.
+ /// </exception>
+
public static object Parse(ReadOnlySpan<byte> utf8Json, Type returnType, JsonSerializerOptions options = null)
{
- if (utf8Json == null)
- throw new ArgumentNullException(nameof(utf8Json));
+ if (returnType == null)
+ throw new ArgumentNullException(nameof(returnType));
return ParseCore(utf8Json, returnType, options);
}
{
public static partial class JsonSerializer
{
- public static ValueTask<TValue> ReadAsync<TValue>(Stream utf8Json, JsonSerializerOptions options = null, CancellationToken cancellationToken = default)
+ /// <summary>
+ /// Read the UTF-8 encoded text representing a single JSON value into a <typeparamref name="TValue"/>.
+ /// The Stream will be read to completion.
+ /// </summary>
+ /// <returns>A <typeparamref name="TValue"/> representation of the JSON value.</returns>
+ /// <param name="utf8Json">JSON data to parse.</param>
+ /// <param name="options">Options to control the behavior during reading.</param>
+ /// <param name="cancellationToken">
+ /// The <see cref="System.Threading.CancellationToken"/> which may be used to cancel the read operation.
+ /// </param>
+ /// <exception cref="JsonReaderException">
+ /// Thrown when the JSON is invalid,
+ /// <typeparamref name="TValue"/> is not compatible with the JSON,
+ /// or when there is remaining data in the Stream.
+ /// </exception>
+ public static ValueTask<TValue> ReadAsync<TValue>(
+ Stream utf8Json,
+ JsonSerializerOptions options = null,
+ CancellationToken cancellationToken = default)
{
if (utf8Json == null)
throw new ArgumentNullException(nameof(utf8Json));
return ReadAsync<TValue>(utf8Json, typeof(TValue), options, cancellationToken);
}
- public static ValueTask<object> ReadAsync(Stream utf8Json, Type returnType, JsonSerializerOptions options = null, CancellationToken cancellationToken = default)
+ /// <summary>
+ /// Read the UTF-8 encoded text representing a single JSON value into a <paramref name="returnType"/>.
+ /// The Stream will be read to completion.
+ /// </summary>
+ /// <returns>A <paramref name="returnType"/> representation of the JSON value.</returns>
+ /// <param name="utf8Json">JSON data to parse.</param>
+ /// <param name="returnType">The type of the object to convert to and return.</param>
+ /// <param name="options">Options to control the behavior during reading.</param>
+ /// <param name="cancellationToken">
+ /// The <see cref="System.Threading.CancellationToken"/> which may be used to cancel the read operation.
+ /// </param>
+ /// <exception cref="System.ArgumentNullException">
+ /// Thrown if <paramref name="utf8Json"/> or <paramref name="returnType"/> is null.
+ /// </exception>
+ /// <exception cref="JsonReaderException">
+ /// Thrown when the JSON is invalid,
+ /// the <paramref name="returnType"/> is not compatible with the JSON,
+ /// or when there is remaining data in the Stream.
+ /// </exception>
+ public static ValueTask<object> ReadAsync(
+ Stream utf8Json,
+ Type returnType,
+ JsonSerializerOptions options = null,
+ CancellationToken cancellationToken = default)
{
if (utf8Json == null)
throw new ArgumentNullException(nameof(utf8Json));
return ReadAsync<object>(utf8Json, returnType, options, cancellationToken);
}
- private static async ValueTask<TValue> ReadAsync<TValue>(Stream utf8Json, Type returnType, JsonSerializerOptions options = null, CancellationToken cancellationToken = default)
+ private static async ValueTask<TValue> ReadAsync<TValue>(
+ Stream utf8Json,
+ Type returnType,
+ JsonSerializerOptions options = null,
+ CancellationToken cancellationToken = default)
{
options ??= s_defaultSettings;
var readerState = new JsonReaderState(options.ReaderOptions);
// todo: switch to ArrayBuffer implementation to handle and simplify the allocs?
- byte[] buffer = ArrayPool<byte>.Shared.Rent(options.EffectiveBufferSize);
+ byte[] buffer = ArrayPool<byte>.Shared.Rent(options.DefaultBufferSize);
int bytesInBuffer = 0;
long totalBytesRead = 0;
int clearMax = 0;
{
public static partial class JsonSerializer
{
+ /// <summary>
+ /// Parse the text representing a single JSON value into a <typeparamref name="TValue"/>.
+ /// </summary>
+ /// <returns>A <typeparamref name="TValue"/> representation of the JSON value.</returns>
+ /// <param name="json">JSON text to parse.</param>
+ /// <param name="options">Options to control the behavior during parsing.</param>
+ /// <exception cref="System.ArgumentNullException">
+ /// Thrown if <paramref name="json"/> is null.
+ /// </exception>
+ /// <exception cref="JsonReaderException">
+ /// Thrown when the JSON is invalid,
+ /// <typeparamref name="TValue"/> is not compatible with the JSON,
+ /// or when there is remaining data in the Stream.
+ /// </exception>
+ /// <remarks>Using a UTF-16 <see cref="System.String"/> is not as efficient as using the
+ /// UTF-8 methods since the implementation natively uses UTF-8.
+ /// </remarks>
public static TValue Parse<TValue>(string json, JsonSerializerOptions options = null)
{
if (json == null)
return (TValue)ParseCore(json, typeof(TValue), options);
}
+ /// <summary>
+ /// Parse the text representing a single JSON value into a <paramref name="returnType"/>.
+ /// </summary>
+ /// <returns>A <paramref name="returnType"/> representation of the JSON value.</returns>
+ /// <param name="json">JSON text to parse.</param>
+ /// <param name="returnType">The type of the object to convert to and return.</param>
+ /// <param name="options">Options to control the behavior during parsing.</param>
+ /// <exception cref="System.ArgumentNullException">
+ /// Thrown if <paramref name="json"/> or <paramref name="returnType"/> is null.
+ /// </exception>
+ /// <exception cref="JsonReaderException">
+ /// Thrown when the JSON is invalid,
+ /// the <paramref name="returnType"/> is not compatible with the JSON,
+ /// or when there is remaining data in the Stream.
+ /// </exception>
+ /// <remarks>Using a UTF-16 <see cref="System.String"/> is not as efficient as using the
+ /// UTF-8 methods since the implementation natively uses UTF-8.
+ /// </remarks>
public static object Parse(string json, Type returnType, JsonSerializerOptions options = null)
{
if (json == null)
if (options == null)
options = s_defaultSettings;
- // todo: use an array pool here for smaller requests to avoid the alloc. Also doc the API that UTF8 is preferred for perf.
+ // todo: use an array pool here for smaller requests to avoid the alloc?
byte[] jsonBytes = JsonReaderHelper.s_utf8Encoding.GetBytes(json);
var readerState = new JsonReaderState(options: options.ReaderOptions);
var reader = new Utf8JsonReader(jsonBytes, isFinalBlock: true, readerState);
namespace System.Text.Json.Serialization
{
+ /// <summary>
+ /// Provides functionality to serialize objects or value types to JSON and
+ /// deserialize JSON into objects or value types.
+ /// </summary>
public static partial class JsonSerializer
{
internal static readonly JsonPropertyInfo s_missingProperty = new JsonPropertyInfoNotNullable<object, object>();
{
public static partial class JsonSerializer
{
- // Name \ feature is pending closure on API review
+ /// <summary>
+ /// Convert the provided value into a <see cref="System.Byte"/> array.
+ /// </summary>
+ /// <returns>A UTF-8 representation of the value.</returns>
+ /// <param name="value">The value to convert.</param>
+ /// <param name="options">Options to control the convertion behavior.</param>
public static byte[] ToBytes<TValue>(TValue value, JsonSerializerOptions options = null)
{
return WriteCoreBytes(value, typeof(TValue), options);
}
- // Name \ feature is pending closure on API review
+ /// <summary>
+ /// Convert the provided value into a <see cref="System.Byte"/> array.
+ /// </summary>
+ /// <returns>A UTF-8 representation of the value.</returns>
+ /// <param name="value">The value to convert.</param>
+ /// <param name="type">The type of the <paramref name="value"/> to convert.</param>
+ /// <param name="options">Options to control the convertion behavior.</param>
public static byte[] ToBytes(object value, Type type, JsonSerializerOptions options = null)
{
VerifyValueAndType(value, type);
byte[] result;
- using (var output = new ArrayBufferWriter<byte>(options.EffectiveBufferSize))
+ using (var output = new ArrayBufferWriter<byte>(options.DefaultBufferSize))
{
WriteCore(output, value, type, options);
result = output.WrittenMemory.ToArray();
string result;
- using (var output = new ArrayBufferWriter<byte>(options.EffectiveBufferSize))
+ using (var output = new ArrayBufferWriter<byte>(options.DefaultBufferSize))
{
WriteCore(output, value, type, options);
result = JsonReaderHelper.TranscodeHelper(output.WrittenMemory.Span);
{
public static partial class JsonSerializer
{
+ /// <summary>
+ /// Convert the provided value to UTF-8 encoded JSON text and write it to the <see cref="System.IO.Stream"/>.
+ /// </summary>
+ /// <returns>A task that represents the asynchronous write operation.</returns>
+ /// <param name="value">The value to convert.</param>
+ /// <param name="utf8Json">The UTF-8 <see cref="System.IO.Stream"/> to write to.</param>
+ /// <param name="options">Options to control the convertion behavior.</param>
+ /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken"/> which may be used to cancel the write operation.</param>
public static Task WriteAsync<TValue>(TValue value, Stream utf8Json, JsonSerializerOptions options = null, CancellationToken cancellationToken = default)
{
return WriteAsyncCore(value, typeof(TValue), utf8Json, options, cancellationToken);
}
+ /// <summary>
+ /// Convert the provided value to UTF-8 encoded JSON text and write it to the <see cref="System.IO.Stream"/>.
+ /// </summary>
+ /// <returns>A task that represents the asynchronous write operation.</returns>
+ /// <param name="value">The value to convert.</param>
+ /// <param name="type">The type of the <paramref name="value"/> to convert.</param>
+ /// <param name="utf8Json">The UTF-8 <see cref="System.IO.Stream"/> to write to.</param>
+ /// <param name="options">Options to control the convertion behavior.</param>
+ /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken"/> which may be used to cancel the write operation.</param>
public static Task WriteAsync(object value, Type type, Stream utf8Json, JsonSerializerOptions options = null, CancellationToken cancellationToken = default)
{
if (utf8Json == null)
var writerState = new JsonWriterState(options.WriterOptions);
- using (var bufferWriter = new ArrayBufferWriter<byte>(options.EffectiveBufferSize))
+ using (var bufferWriter = new ArrayBufferWriter<byte>(options.DefaultBufferSize))
{
if (value == null)
{
{
public static partial class JsonSerializer
{
+ /// <summary>
+ /// Convert the provided value into a <see cref="System.String"/>.
+ /// </summary>
+ /// <returns>A <see cref="System.String"/> representation of the value.</returns>
+ /// <param name="value">The value to convert.</param>
+ /// <param name="options">Options to control the convertion behavior.</param>
+ /// <remarks>Using a <see cref="System.String"/> is not as efficient as using UTF-8
+ /// encoding since the implementation internally uses UTF-8. See also <see cref="ToBytes"/>
+ /// and <see cref="WriteAsync"/>.
+ /// </remarks>
public static string ToString<TValue>(TValue value, JsonSerializerOptions options = null)
{
return ToStringInternal(value, typeof(TValue), options);
}
+ /// <summary>
+ /// Convert the provided value into a <see cref="System.String"/>.
+ /// </summary>
+ /// <returns>A <see cref="System.String"/> representation of the value.</returns>
+ /// <param name="value">The value to convert.</param>
+ /// <param name="type">The type of the <paramref name="value"/> to convert.</param>
+ /// <param name="options">Options to control the convertion behavior.</param>
+ /// <remarks>Using a <see cref="System.String"/> is not as efficient as using UTF-8
+ /// encoding since the implementation internally uses UTF-8. See also <see cref="ToBytes"/>
+ /// and <see cref="WriteAsync"/>.
+ /// </remarks>
public static string ToString(object value, Type type, JsonSerializerOptions options = null)
{
VerifyValueAndType(value, type);
namespace System.Text.Json.Serialization
{
+ /// <summary>
+ /// Provides options to be used with <see cref="JsonSerializer"/>.
+ /// </summary>
public sealed class JsonSerializerOptions
{
- internal const int BufferSizeUnspecified = -1;
internal const int BufferSizeDefault = 16 * 1024;
private ClassMaterializer _classMaterializerStrategy;
- private int _defaultBufferSize = BufferSizeUnspecified;
+ private int _defaultBufferSize = BufferSizeDefault;
private static readonly ConcurrentDictionary<Type, JsonClassInfo> s_classes = new ConcurrentDictionary<Type, JsonClassInfo>();
+ /// <summary>
+ /// Constructs a new <see cref="JsonSerializerOptions"/> instance.
+ /// </summary>
public JsonSerializerOptions() { }
internal JsonClassInfo GetOrAddClass(Type classType)
return result;
}
+ /// <summary>
+ /// Options to control the <see cref="Utf8JsonReader"/>.
+ /// </summary>
public JsonReaderOptions ReaderOptions { get; set; }
+
+ /// <summary>
+ /// Options to control the <see cref="Utf8JsonWriter"/>.
+ /// </summary>
public JsonWriterOptions WriterOptions { get; set; }
+ /// <summary>
+ /// The default buffer size in bytes used when creating temporary buffers.
+ /// </summary>
+ /// <remarks>The default size is 16K.</remarks>
+ /// <exception cref="System.ArgumentException">Thrown when the buffer size is less than 1.</exception>
public int DefaultBufferSize
{
get
}
set
{
- if (value == 0 || value < BufferSizeUnspecified)
+ if (value < 1)
{
throw new ArgumentException(SR.SerializationInvalidBufferSize);
}
_defaultBufferSize = value;
-
- if (_defaultBufferSize == BufferSizeUnspecified)
- {
- EffectiveBufferSize = BufferSizeDefault;
- }
- else
- {
- EffectiveBufferSize = _defaultBufferSize;
- }
}
}
+ /// <summary>
+ /// Determines whether null values of properties are ignored or whether they are written to the JSON.
+ /// </summary>
public bool IgnoreNullPropertyValueOnWrite { get; set; }
- public bool IgnoreNullPropertyValueOnRead { get; set; }
- // Used internally for performance to avoid checking BufferSizeUnspecified.
- internal int EffectiveBufferSize { get; private set; } = BufferSizeDefault;
+ /// <summary>
+ /// Determines whether null values in the JSON are ignored or whether they are set on properties.
+ /// </summary>
+ public bool IgnoreNullPropertyValueOnRead { get; set; }
internal ClassMaterializer ClassMaterializerStrategy
{
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Xunit;
+
+namespace System.Text.Json.Serialization.Tests
+{
+ public static partial class OptionsTests
+ {
+ [Fact]
+ public static void DefaultBufferSizeFail()
+ {
+ Assert.Throws<ArgumentException>(() => new JsonSerializerOptions().DefaultBufferSize = 0);
+ Assert.Throws<ArgumentException>(() => new JsonSerializerOptions().DefaultBufferSize = -1);
+ }
+
+ [Fact]
+ public static void DefaultBufferSize()
+ {
+ var options = new JsonSerializerOptions();
+
+ Assert.Equal(16 * 1024, options.DefaultBufferSize);
+
+ options.DefaultBufferSize = 1;
+ Assert.Equal(1, options.DefaultBufferSize);
+ }
+ }
+}
public static class SpanTests
{
[Fact]
- public static void NullObjectInputFail()
+ public static void ParseNullTypeFail()
{
- Assert.Throws<ArgumentNullException>(() => JsonSerializer.Parse<string>((ReadOnlySpan<byte>)null));
+ Assert.Throws<ArgumentNullException>(() => JsonSerializer.Parse(new ReadOnlySpan<byte>(), (Type)null));
}
[Theory]
}
[Fact]
- public static void VerifyValueFail()
+ public static void ToStringNullTypeFail()
{
Assert.Throws<ArgumentNullException>(() => JsonSerializer.ToString(new object(), (Type)null));
}
public static partial class StreamTests
{
[Fact]
- public static async void NullObjectInputFalse()
+ public static async void NullArgumentFail()
{
await Assert.ThrowsAsync<ArgumentNullException>(async () => await JsonSerializer.ReadAsync<string>((Stream)null));
+ await Assert.ThrowsAsync<ArgumentNullException>(async () => await JsonSerializer.ReadAsync(new MemoryStream(), (Type)null));
}
[Fact]
public static partial class StringTests
{
[Fact]
- public static void NullObjectInputFail()
+ public static void ParseNullArgumentFail()
{
-
Assert.Throws<ArgumentNullException>(() => JsonSerializer.Parse<string>((string)null));
+ Assert.Throws<ArgumentNullException>(() => JsonSerializer.Parse("1", (Type)null));
}
[Fact]
public static partial class StringTests
{
[Fact]
- public static void VerifyValueFail()
+ public static void ToStringNullArgumentFail()
{
Assert.Throws<ArgumentNullException>(() => JsonSerializer.ToString("", (Type)null));
}
<Compile Include="Serialization\EnumTests.cs" />
<Compile Include="Serialization\Null.ReadTests.cs" />
<Compile Include="Serialization\Null.WriteTests.cs" />
+ <Compile Include="Serialization\OptionsTests.cs" />
<Compile Include="Serialization\PolymorphicTests.cs" />
<Compile Include="Serialization\PropertyVisibilityTests.cs" />
<Compile Include="Serialization\SpanTests.cs" />