Exemplo n.º 1
0
        /// <summary>
        /// Parses a continuation token and returns the corresponding to the
        /// next page's <see cref="SearchOptions"/>.
        /// </summary>
        /// <param name="continuationToken">
        /// The serialized continuation token.
        /// </param>
        /// <returns>The continuation token's next page options.</returns>
        public static SearchOptions Deserialize(string continuationToken)
        {
            Argument.AssertNotNullOrEmpty(continuationToken, nameof(continuationToken));
            byte[] decoded = Convert.FromBase64String(continuationToken);
            try
            {
                using JsonDocument json = JsonDocument.Parse(decoded);
                if (json.RootElement.ValueKind == JsonValueKind.Object &&
                    json.RootElement.TryGetProperty(ApiVersionName, out JsonElement apiVersion) &&
                    apiVersion.ValueKind == JsonValueKind.String &&
                    // Today we only validate against a single known version,
                    // but in the future we may want to support a range of
                    // valid continuation token serialization formats.  This
                    // will need to be updated accordingly.
                    string.Equals(
                        apiVersion.GetString(),
                        SearchClientOptions.ContinuationTokenVersion.ToVersionString(),
                        StringComparison.OrdinalIgnoreCase) &&
                    json.RootElement.TryGetProperty(NextPageParametersName, out JsonElement nextPageParams) &&
                    nextPageParams.ValueKind == JsonValueKind.Object)
                {
                    // We only use the nextPageParameters because we do all of
                    // our searching via HTTP POST requests
                    return(SearchOptions.DeserializeSearchOptions(nextPageParams));
                }
            }
            catch (JsonException)
            {
            }

            throw new ArgumentException("Invalid continuation token", nameof(continuationToken));
        }
        internal static SearchDocumentsResult DeserializeSearchDocumentsResult(JsonElement element)
        {
            Optional <long>   odataCount     = default;
            Optional <double> searchCoverage = default;
            Optional <IReadOnlyDictionary <string, IList <FacetResult> > > searchFacets = default;
            Optional <SearchOptions>     searchNextPageParameters = default;
            IReadOnlyList <SearchResult> value         = default;
            Optional <string>            odataNextLink = default;

            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("@odata.count"))
                {
                    odataCount = property.Value.GetInt64();
                    continue;
                }
                if (property.NameEquals("@search.coverage"))
                {
                    searchCoverage = property.Value.GetDouble();
                    continue;
                }
                if (property.NameEquals("@search.facets"))
                {
                    Dictionary <string, IList <FacetResult> > dictionary = new Dictionary <string, IList <FacetResult> >();
                    foreach (var property0 in property.Value.EnumerateObject())
                    {
                        List <FacetResult> array = new List <FacetResult>();
                        foreach (var item in property0.Value.EnumerateArray())
                        {
                            array.Add(FacetResult.DeserializeFacetResult(item));
                        }
                        dictionary.Add(property0.Name, array);
                    }
                    searchFacets = dictionary;
                    continue;
                }
                if (property.NameEquals("@search.nextPageParameters"))
                {
                    searchNextPageParameters = SearchOptions.DeserializeSearchOptions(property.Value);
                    continue;
                }
                if (property.NameEquals("value"))
                {
                    List <SearchResult> array = new List <SearchResult>();
                    foreach (var item in property.Value.EnumerateArray())
                    {
                        array.Add(SearchResult.DeserializeSearchResult(item));
                    }
                    value = array;
                    continue;
                }
                if (property.NameEquals("@odata.nextLink"))
                {
                    odataNextLink = property.Value.GetString();
                    continue;
                }
            }
            return(new SearchDocumentsResult(Optional.ToNullable(odataCount), Optional.ToNullable(searchCoverage), Optional.ToDictionary(searchFacets), searchNextPageParameters.Value, value, odataNextLink.Value));
        }
Exemplo n.º 3
0
        /// <summary>
        /// Read the @search.nextPageParameters property value.
        /// </summary>
        /// <param name="reader">The JSON reader.</param>
        /// <returns>The next SearchOptions.</returns>
        private static SearchOptions ReadNextPageOptions(ref Utf8JsonReader reader)
        {
            // Next page options aren't required, so short circuit if nothing
            // is found
            if (reader.TokenType == JsonTokenType.Null)
            {
                return(null);
            }

            // Use the generated SearchOptions parsing code
            using JsonDocument doc = JsonDocument.ParseValue(ref reader);
            return(SearchOptions.DeserializeSearchOptions(doc.RootElement));
        }
        #pragma warning disable CS1572 // Not all parameters will be used depending on feature flags
        /// <summary>
        /// Deserialize the SearchResults.
        /// </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 SearchResults.</returns>
        internal static async Task <SearchResults <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;

            SearchResults <T> results = new SearchResults <T>();

            foreach (JsonProperty prop in doc.RootElement.EnumerateObject())
            {
                if (prop.NameEquals(Constants.ODataCountKeyJson.EncodedUtf8Bytes) &&
                    prop.Value.ValueKind != JsonValueKind.Null)
                {
                    results.TotalCount = prop.Value.GetInt64();
                }
                else if (prop.NameEquals(Constants.SearchCoverageKeyJson.EncodedUtf8Bytes) &&
                         prop.Value.ValueKind != JsonValueKind.Null)
                {
                    results.Coverage = prop.Value.GetDouble();
                }
                else if (prop.NameEquals(Constants.SearchFacetsKeyJson.EncodedUtf8Bytes))
                {
                    results.Facets = new Dictionary <string, IList <FacetResult> >();
                    foreach (JsonProperty facetObject in prop.Value.EnumerateObject())
                    {
                        // Get the values of the facet
                        List <FacetResult> facets = new List <FacetResult>();
                        foreach (JsonElement facetValue in facetObject.Value.EnumerateArray())
                        {
                            Dictionary <string, object> facetValues = new Dictionary <string, object>();
                            long?facetCount = null;
                            foreach (JsonProperty facetProperty in facetValue.EnumerateObject())
                            {
                                if (facetProperty.NameEquals(Constants.CountKeyJson.EncodedUtf8Bytes))
                                {
                                    if (facetProperty.Value.ValueKind != JsonValueKind.Null)
                                    {
                                        facetCount = facetProperty.Value.GetInt64();
                                    }
                                }
                                else
                                {
                                    object value = facetProperty.Value.GetSearchObject();
                                    facetValues[facetProperty.Name] = value;
                                }
                            }
                            facets.Add(new FacetResult(facetCount, facetValues));
                        }
                        // Add the facet to the results
                        results.Facets[facetObject.Name] = facets;
                    }
                }
                else if (prop.NameEquals(Constants.ODataNextLinkKeyJson.EncodedUtf8Bytes))
                {
                    results.NextUri = new Uri(prop.Value.GetString());
                }
                else if (prop.NameEquals(Constants.SearchNextPageKeyJson.EncodedUtf8Bytes))
                {
                    results.NextOptions = SearchOptions.DeserializeSearchOptions(prop.Value);
                }
                else if (prop.NameEquals(Constants.ValueKeyJson.EncodedUtf8Bytes))
                {
                    foreach (JsonElement element in prop.Value.EnumerateArray())
                    {
                        SearchResult <T> result = await SearchResult <T> .DeserializeAsync(
                            element,
#if EXPERIMENTAL_SERIALIZER
                            serializer,
#endif
                            defaultSerializerOptions,
                            async,
                            cancellationToken)
                                                  .ConfigureAwait(false);

                        results.Values.Add(result);
                    }
                }
            }
            return(results);
        }
        internal static SearchDocumentsResult DeserializeSearchDocumentsResult(JsonElement element)
        {
            long?  odataCount     = default;
            double?searchCoverage = default;
            IReadOnlyDictionary <string, IList <FacetResult> > searchFacets = default;
            SearchOptions searchNextPageParameters = default;
            IReadOnlyList <SearchResult> value     = default;
            string odataNextLink = default;

            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("@odata.count"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        continue;
                    }
                    odataCount = property.Value.GetInt64();
                    continue;
                }
                if (property.NameEquals("@search.coverage"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        continue;
                    }
                    searchCoverage = property.Value.GetDouble();
                    continue;
                }
                if (property.NameEquals("@search.facets"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        continue;
                    }
                    Dictionary <string, IList <FacetResult> > dictionary = new Dictionary <string, IList <FacetResult> >();
                    foreach (var property0 in property.Value.EnumerateObject())
                    {
                        if (property0.Value.ValueKind == JsonValueKind.Null)
                        {
                            dictionary.Add(property0.Name, null);
                        }
                        else
                        {
                            List <FacetResult> array = new List <FacetResult>();
                            foreach (var item in property0.Value.EnumerateArray())
                            {
                                if (item.ValueKind == JsonValueKind.Null)
                                {
                                    array.Add(null);
                                }
                                else
                                {
                                    array.Add(FacetResult.DeserializeFacetResult(item));
                                }
                            }
                            dictionary.Add(property0.Name, array);
                        }
                    }
                    searchFacets = dictionary;
                    continue;
                }
                if (property.NameEquals("@search.nextPageParameters"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        continue;
                    }
                    searchNextPageParameters = SearchOptions.DeserializeSearchOptions(property.Value);
                    continue;
                }
                if (property.NameEquals("value"))
                {
                    List <SearchResult> array = new List <SearchResult>();
                    foreach (var item in property.Value.EnumerateArray())
                    {
                        if (item.ValueKind == JsonValueKind.Null)
                        {
                            array.Add(null);
                        }
                        else
                        {
                            array.Add(SearchResult.DeserializeSearchResult(item));
                        }
                    }
                    value = array;
                    continue;
                }
                if (property.NameEquals("@odata.nextLink"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        continue;
                    }
                    odataNextLink = property.Value.GetString();
                    continue;
                }
            }
            return(new SearchDocumentsResult(odataCount, searchCoverage, searchFacets, searchNextPageParameters, value, odataNextLink));
        }
Exemplo n.º 6
0
        internal static SearchDocumentsResult DeserializeSearchDocumentsResult(JsonElement element)
        {
            SearchDocumentsResult result = new SearchDocumentsResult();

            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("@odata.count"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        continue;
                    }
                    result.Count = property.Value.GetInt64();
                    continue;
                }
                if (property.NameEquals("@search.coverage"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        continue;
                    }
                    result.Coverage = property.Value.GetDouble();
                    continue;
                }
                if (property.NameEquals("@search.facets"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        continue;
                    }
                    result.Facets = new Dictionary <string, IList <FacetResult> >();
                    foreach (var property0 in property.Value.EnumerateObject())
                    {
                        IList <FacetResult> value = new List <FacetResult>();
                        foreach (var item in property0.Value.EnumerateArray())
                        {
                            value.Add(FacetResult.DeserializeFacetResult(item));
                        }
                        result.Facets.Add(property0.Name, value);
                    }
                    continue;
                }
                if (property.NameEquals("@search.nextPageParameters"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        continue;
                    }
                    result.NextPageParameters = SearchOptions.DeserializeSearchOptions(property.Value);
                    continue;
                }
                if (property.NameEquals("value"))
                {
                    foreach (var item in property.Value.EnumerateArray())
                    {
                        result.Results.Add(SearchResult.DeserializeSearchResult(item));
                    }
                    continue;
                }
                if (property.NameEquals("@odata.nextLink"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        continue;
                    }
                    result.NextLink = property.Value.GetString();
                    continue;
                }
            }
            return(result);
        }