public CatalogSearchQuery CreateFromQuery()
        {
            var ctx = _httpContext;

            if (ctx.Request == null)
            {
                return(null);
            }

            var routeData  = ctx.Request.RequestContext.RouteData;
            var area       = routeData.GetAreaName();
            var controller = routeData.GetRequiredString("controller");
            var action     = routeData.GetRequiredString("action");
            var origin     = "{0}{1}/{2}".FormatInvariant(area == null ? "" : area + "/", controller, action);
            var fields     = new List <string> {
                "name"
            };
            var term            = GetValueFor <string>("q");
            var isInstantSearch = origin.IsCaseInsensitiveEqual("Search/InstantSearch");

            if (isInstantSearch)
            {
                fields.Add("shortdescription");
                fields.Add("tagname");

                foreach (var fieldName in _instantSearchFields)
                {
                    if (_searchSettings.SearchFields.Contains(fieldName))
                    {
                        fields.Add(fieldName);
                    }
                }
            }
            else
            {
                fields.AddRange(_searchSettings.SearchFields);
            }

            var query = new CatalogSearchQuery(fields.ToArray(), term, _searchSettings.SearchMode)
                        .OriginatesFrom(origin)
                        .WithLanguage(_services.WorkContext.WorkingLanguage)
                        .WithCurrency(_services.WorkContext.WorkingCurrency)
                        .VisibleIndividuallyOnly(true)
                        .BuildFacetMap(!isInstantSearch);

            // Visibility.
            query.VisibleOnly(!QuerySettings.IgnoreAcl ? _services.WorkContext.CurrentCustomer : null);

            // Store.
            if (!QuerySettings.IgnoreMultiStore)
            {
                query.HasStoreId(_services.StoreContext.CurrentStore.Id);
            }

            // Availability.
            ConvertAvailability(query, routeData, origin);

            // Instant-Search never uses these filter parameters.
            if (!isInstantSearch)
            {
                ConvertPagingSorting(query, routeData, origin);
                ConvertPrice(query, routeData, origin);
                ConvertCategory(query, routeData, origin);
                ConvertManufacturer(query, routeData, origin);
                ConvertRating(query, routeData, origin);
                ConvertNewArrivals(query, routeData, origin);
                ConvertDeliveryTime(query, routeData, origin);
            }

            OnConverted(query, routeData, origin);

            Current = query;
            return(query);
        }
        public async Task <CatalogSearchQuery> CreateFromQueryAsync()
        {
            var ctx = _httpContextAccessor.HttpContext;

            if (ctx?.Request == null)
            {
                return(null);
            }

            var area       = ctx.Request.RouteValues.GetAreaName();
            var controller = ctx.Request.RouteValues.GetControllerName();
            var action     = ctx.Request.RouteValues.GetActionName();
            var origin     = "{0}{1}/{2}".FormatInvariant(area == null ? "" : area + "/", controller, action);
            var fields     = new List <string> {
                "name"
            };
            var term            = GetValueFor <string>("q");
            var isInstantSearch = origin.EqualsNoCase("Search/InstantSearch");

            if (isInstantSearch)
            {
                fields.Add("shortdescription");
                fields.Add("tagname");

                foreach (var fieldName in _instantSearchFields)
                {
                    if (_searchSettings?.SearchFields?.Contains(fieldName) ?? false)
                    {
                        fields.Add(fieldName);
                    }
                }
            }
            else if (_searchSettings.SearchFields != null)
            {
                fields.AddRange(_searchSettings.SearchFields);
            }

            var query = new CatalogSearchQuery(fields.ToArray(), term, _searchSettings.SearchMode)
                        .OriginatesFrom(origin)
                        .WithLanguage(_services.WorkContext.WorkingLanguage)
                        .WithCurrency(_services.WorkContext.WorkingCurrency)
                        .BuildFacetMap(!isInstantSearch);

            // Visibility.
            query.VisibleOnly(!_services.DbContext.QuerySettings.IgnoreAcl ? _services.WorkContext.CurrentCustomer : null);

            if (isInstantSearch || origin.EqualsNoCase("Search/Search"))
            {
                query.WithVisibility(ProductVisibility.SearchResults);
            }
            else
            {
                query.WithVisibility(ProductVisibility.Full);
            }

            // Store.
            if (!_services.DbContext.QuerySettings.IgnoreMultiStore)
            {
                query.HasStoreId(_services.StoreContext.CurrentStore.Id);
            }

            // Availability.
            ConvertAvailability(query, origin);

            // Instant-Search never uses these filter parameters.
            if (!isInstantSearch)
            {
                await ConvertPagingSortingAsync(query, origin);

                ConvertPrice(query, origin);
                ConvertCategory(query, origin);
                ConvertManufacturer(query, origin);
                ConvertRating(query, origin);
                ConvertNewArrivals(query, origin);
                ConvertDeliveryTime(query, origin);
            }

            await OnConvertedAsync(query, origin);

            Current = query;
            return(query);
        }