/// <summary> /// Parse a SearchSuggestion and its model. /// </summary> /// <param name="reader">The JSON reader.</param> /// <param name="typeToConvert">The type to parse into.</param> /// <param name="options">Serialization options.</param> /// <returns>The deserialized suggestion.</returns> public override SearchSuggestion <T> Read( ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { Debug.Assert(options != null); SearchSuggestion <T> suggestion = new SearchSuggestion <T>(); // Clone the reader so we can get the search text property without // advancing the reader over any properties needed to deserialize // the user's model type. Utf8JsonReader clone = reader; clone.Expects(JsonTokenType.StartObject); while (clone.Read() && clone.TokenType != JsonTokenType.EndObject) { string name = clone.ExpectsPropertyName(); if (name == Constants.SearchTextKey) { suggestion.Text = clone.ExpectsString(); break; } } // Deserialize the model T document = JsonSerializer.Deserialize <T>(ref reader, options); suggestion.Document = document; return(suggestion); }
#pragma warning disable CS1572 // Not all parameters will be used depending on feature flags /// <summary> /// Deserialize a SearchSuggestion and its model. /// </summary> /// <param name="element">A JSON element.</param> /// <param name="serializer"> /// Optional serializer that can be used to customize the serialization /// of strongly typed models. /// </param> /// <param name="options">JSON serializer options.</param> /// <param name="async">Whether to execute sync or async.</param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate notifications /// that the operation should be canceled. /// </param> /// <returns>Deserialized SearchSuggestion.</returns> internal static async Task <SearchSuggestion <T> > DeserializeAsync( JsonElement element, #if EXPERIMENTAL_SERIALIZER ObjectSerializer serializer, #endif JsonSerializerOptions options, bool async, CancellationToken cancellationToken) #pragma warning restore CS1572 { Debug.Assert(options != null); SearchSuggestion <T> suggestion = new SearchSuggestion <T>(); foreach (JsonProperty prop in element.EnumerateObject()) { if (prop.NameEquals(Constants.SearchTextKeyJson.EncodedUtf8Bytes)) { suggestion.Text = prop.Value.GetString(); break; // We only have one non-model property } } // Deserialize the model #if EXPERIMENTAL_SERIALIZER if (serializer != null) { using Stream stream = element.ToStream(); T document = async ? (T)await serializer.DeserializeAsync(stream, typeof(T)).ConfigureAwait(false) : (T)serializer.Deserialize(stream, typeof(T)); suggestion.Document = document; } else { #endif T document; if (async) { using Stream stream = element.ToStream(); document = await JsonSerializer.DeserializeAsync <T>(stream, options, cancellationToken).ConfigureAwait(false); } else { document = JsonSerializer.Deserialize <T>(element.GetRawText(), options); } suggestion.Document = document; #if EXPERIMENTAL_SERIALIZER } #endif return(suggestion); }
#pragma warning disable CS1572 // Not all parameters will be used depending on feature flags /// <summary> /// Deserialize the SuggestResults. /// </summary> /// <param name="json">A JSON stream.</param> /// <param name="serializer"> /// Optional serializer that can be used to customize the serialization /// of strongly typed models. /// </param> /// <param name="async">Whether to execute sync or async.</param> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate notifications /// that the operation should be canceled. /// </param> /// <returns>Deserialized SuggestResults.</returns> internal static async Task <SuggestResults <T> > DeserializeAsync( Stream json, #if EXPERIMENTAL_SERIALIZER ObjectSerializer serializer, #endif bool async, CancellationToken cancellationToken) #pragma warning restore CS1572 { // Parse the JSON using JsonDocument doc = async ? await JsonDocument.ParseAsync(json, cancellationToken : cancellationToken).ConfigureAwait(false) : JsonDocument.Parse(json); JsonSerializerOptions defaultSerializerOptions = JsonSerialization.SerializerOptions; SuggestResults <T> suggestions = new SuggestResults <T>(); foreach (JsonProperty prop in doc.RootElement.EnumerateObject()) { if (prop.NameEquals(Constants.SearchCoverageKeyJson.EncodedUtf8Bytes) && prop.Value.ValueKind != JsonValueKind.Null) { suggestions.Coverage = prop.Value.GetDouble(); } else if (prop.NameEquals(Constants.ValueKeyJson.EncodedUtf8Bytes)) { List <SearchSuggestion <T> > results = new List <SearchSuggestion <T> >(); foreach (JsonElement element in prop.Value.EnumerateArray()) { SearchSuggestion <T> suggestion = await SearchSuggestion <T> .DeserializeAsync( element, #if EXPERIMENTAL_SERIALIZER serializer, #endif defaultSerializerOptions, async, cancellationToken) .ConfigureAwait(false); results.Add(suggestion); } suggestions.Results = new ReadOnlyCollection <SearchSuggestion <T> >(results); } } return(suggestions); }
/// <summary> /// Parse the SuggestResults and its suggestions. /// </summary> /// <param name="reader">The JSON reader.</param> /// <param name="typeToConvert">The type to parse into.</param> /// <param name="options">Serialization options.</param> /// <returns>The deserialized suggestions.</returns> public override SuggestResults <T> Read( ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { Debug.Assert(typeToConvert != null); Debug.Assert(typeToConvert.IsAssignableFrom(typeof(SuggestResults <T>))); Debug.Assert(options != null); SuggestResults <T> suggestions = new SuggestResults <T>(); reader.Expects(JsonTokenType.StartObject); while (reader.Read() && reader.TokenType != JsonTokenType.EndObject) { switch (reader.ExpectsPropertyName()) { case Constants.SearchCoverageKey: suggestions.Coverage = reader.ExpectsNullableDouble(); break; case Constants.ValueKey: reader.Expects(JsonTokenType.StartArray); while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) { SearchSuggestion <T> suggestion = _suggestionConverter.Read(ref reader, _suggestionType, options); suggestions.Results.Add(suggestion); } break; default: // Ignore other properties (including OData context, etc.) reader.Skip(); break; } } return(suggestions); }
/// <summary> /// Serializing SearchSuggestion isn't supported as it's an output only /// model type. This always fails. /// </summary> /// <param name="writer">The JSON writer.</param> /// <param name="value">The suggestion.</param> /// <param name="options">Serialization options.</param> public override void Write(Utf8JsonWriter writer, SearchSuggestion <T> value, JsonSerializerOptions options) => throw new NotSupportedException($"{nameof(SearchSuggestion<T>)} cannot be serialized to JSON.");