public async Task <IHttpActionResult> Search( ODataQueryOptions <V1FeedPackage> options, [FromODataUri] string searchTerm = "", [FromODataUri] string targetFramework = "") { // Handle OData-style |-separated list of frameworks. string[] targetFrameworkList = (targetFramework ?? "").Split(new[] { '\'', '|' }, StringSplitOptions.RemoveEmptyEntries); // For now, we'll just filter on the first one. if (targetFrameworkList.Length > 0) { // Until we support multiple frameworks, we need to prefer aspnet50 over aspnetcore50. if (targetFrameworkList.Contains("aspnet50")) { targetFramework = "aspnet50"; } else { targetFramework = targetFrameworkList[0]; } } // Peform actual search var packages = _packagesRepository.GetAll() .Include(p => p.PackageRegistration) .Include(p => p.PackageRegistration.Owners) .Where(p => p.Listed && !p.IsPrerelease && !p.Deleted) .OrderBy(p => p.PackageRegistration.Id).ThenBy(p => p.Version) .AsNoTracking(); // todo: search hijack should take queryOptions instead of manually parsing query options var searchAdaptorResult = await SearchAdaptor.SearchCore( _searchService, GetTraditionalHttpContext().Request, packages, searchTerm, targetFramework, false, curatedFeed : null); // Packages provided by search service (even when not hijacked) var query = searchAdaptorResult.Packages; // If intercepted, create a paged queryresult if (searchAdaptorResult.ResultsAreProvidedBySearchService) { // Add explicit Take() needed to limit search hijack result set size if $top is specified var totalHits = query.LongCount(); var pagedQueryable = query .Take(options.Top != null ? Math.Min(options.Top.Value, MaxPageSize) : MaxPageSize) .ToV1FeedPackageQuery(GetSiteRoot()); return(QueryResult(options, pagedQueryable, MaxPageSize, totalHits, (o, s, resultCount) => SearchAdaptor.GetNextLink(Request.RequestUri, resultCount, new { searchTerm, targetFramework }, o, s))); } // If not, just let OData handle things var queryable = query.ToV1FeedPackageQuery(GetSiteRoot()); return(QueryResult(options, queryable, MaxPageSize)); }
public async Task <IHttpActionResult> Search( ODataQueryOptions <V1FeedPackage> options, [FromODataUri] string searchTerm = "", [FromODataUri] string targetFramework = "") { // Handle OData-style |-separated list of frameworks. string[] targetFrameworkList = (targetFramework ?? "").Split(new[] { '\'', '|' }, StringSplitOptions.RemoveEmptyEntries); // For now, we'll just filter on the first one. if (targetFrameworkList.Length > 0) { // Until we support multiple frameworks, we need to prefer aspnet50 over aspnetcore50. if (targetFrameworkList.Contains("aspnet50")) { targetFramework = "aspnet50"; } else { targetFramework = targetFrameworkList[0]; } } // Perform actual search var packages = GetAll() .Include(p => p.PackageRegistration) .Include(p => p.PackageRegistration.Owners) .Where(p => p.Listed && !p.IsPrerelease && p.PackageStatusKey == PackageStatus.Available) .Where(SemVerLevelKey.IsUnknownPredicate()) .OrderBy(p => p.PackageRegistration.Id).ThenBy(p => p.Version) .AsNoTracking(); // todo: search hijack should take queryOptions instead of manually parsing query options var searchService = _searchServiceFactory.GetService(); var searchAdaptorResult = await SearchAdaptor.SearchCore( searchService, GetTraditionalHttpContext().Request, packages, searchTerm, targetFramework, includePrerelease : false, semVerLevel : null); // Packages provided by search service (even when not hijacked) var query = searchAdaptorResult.Packages; bool?customQuery = null; // If intercepted, create a paged queryresult if (searchAdaptorResult.ResultsAreProvidedBySearchService) { customQuery = false; // Add explicit Take() needed to limit search hijack result set size if $top is specified var totalHits = query.LongCount(); var pagedQueryable = query .Take(options.Top != null ? Math.Min(options.Top.Value, MaxPageSize) : MaxPageSize) .ToV1FeedPackageQuery(GetSiteRoot()); return(TrackedQueryResult( options, pagedQueryable, MaxPageSize, totalHits, (o, s, resultCount) => SearchAdaptor.GetNextLink(Request.RequestUri, resultCount, new { searchTerm, targetFramework }, o, s), customQuery)); } else { customQuery = true; } if (!ODataQueryVerifier.AreODataOptionsAllowed(options, ODataQueryVerifier.V1Search, _configurationService.Current.IsODataFilterEnabled, nameof(Search))) { return(BadRequest(ODataQueryVerifier.GetValidationFailedMessage(options))); } // If not, just let OData handle things var queryable = query.ToV1FeedPackageQuery(GetSiteRoot()); return(TrackedQueryResult(options, queryable, MaxPageSize, customQuery)); }
public async Task <IHttpActionResult> Search( ODataQueryOptions <V2FeedPackage> options, string curatedFeedName, [FromODataUri] string searchTerm = "", [FromODataUri] string targetFramework = "", [FromODataUri] bool includePrerelease = false) { if (!_entities.CuratedFeeds.Any(cf => cf.Name == curatedFeedName)) { return(NotFound()); } // Handle OData-style |-separated list of frameworks. string[] targetFrameworkList = (targetFramework ?? "").Split(new[] { '\'', '|' }, StringSplitOptions.RemoveEmptyEntries); // For now, we'll just filter on the first one. if (targetFrameworkList.Length > 0) { // Until we support multiple frameworks, we need to prefer aspnet50 over aspnetcore50. if (targetFrameworkList.Contains("aspnet50")) { targetFramework = "aspnet50"; } else { targetFramework = targetFrameworkList[0]; } } // Peform actual search var curatedFeed = _curatedFeedService.GetFeedByName(curatedFeedName, includePackages: false); var packages = _curatedFeedService.GetPackages(curatedFeedName) .OrderBy(p => p.PackageRegistration.Id).ThenBy(p => p.Version); // todo: search hijack should take queryOptions instead of manually parsing query options var searchAdaptorResult = await SearchAdaptor.SearchCore( _searchService, GetTraditionalHttpContext().Request, packages, searchTerm, targetFramework, includePrerelease, curatedFeed : curatedFeed); // Packages provided by search service (even when not hijacked) var query = searchAdaptorResult.Packages; // If intercepted, create a paged queryresult if (searchAdaptorResult.ResultsAreProvidedBySearchService) { // Add explicit Take() needed to limit search hijack result set size if $top is specified var totalHits = query.LongCount(); var pagedQueryable = query .Take(options.Top != null ? Math.Min(options.Top.Value, MaxPageSize) : MaxPageSize) .ToV2FeedPackageQuery(GetSiteRoot(), _configurationService.Features.FriendlyLicenses); return(QueryResult(options, pagedQueryable, MaxPageSize, totalHits, (o, s, resultCount) => { // The nuget.exe 2.x list command does not like the next link at the bottom when a $top is passed. // Strip it of for backward compatibility. if (o.Top == null || (resultCount.HasValue && o.Top.Value >= resultCount.Value)) { return SearchAdaptor.GetNextLink(Request.RequestUri, resultCount, new { searchTerm, targetFramework, includePrerelease }, o, s); } return null; })); } // If not, just let OData handle things var queryable = query.ToV2FeedPackageQuery(GetSiteRoot(), _configurationService.Features.FriendlyLicenses); return(QueryResult(options, queryable, MaxPageSize)); }
public async Task <IHttpActionResult> Search( ODataQueryOptions <V2FeedPackage> options, [FromODataUri] string searchTerm = "", [FromODataUri] string targetFramework = "", [FromODataUri] bool includePrerelease = false, [FromUri] string semVerLevel = null) { // Handle OData-style |-separated list of frameworks. string[] targetFrameworkList = (targetFramework ?? "").Split(new[] { '\'', '|' }, StringSplitOptions.RemoveEmptyEntries); // For now, we'll just filter on the first one. if (targetFrameworkList.Length > 0) { // Until we support multiple frameworks, we need to prefer aspnet50 over aspnetcore50. if (targetFrameworkList.Contains("aspnet50")) { targetFramework = "aspnet50"; } else { targetFramework = targetFrameworkList[0]; } } // Perform actual search var packages = _packagesRepository.GetAll() .Include(p => p.PackageRegistration) .Include(p => p.PackageRegistration.Owners) .Where(p => p.Listed && p.PackageStatusKey == PackageStatus.Available) .Where(SemVerLevelKey.IsPackageCompliantWithSemVerLevelPredicate(semVerLevel)) .OrderBy(p => p.PackageRegistration.Id).ThenBy(p => p.Version) .AsNoTracking(); // todo: search hijack should take options instead of manually parsing query options var searchAdaptorResult = await SearchAdaptor.SearchCore( _searchService, GetTraditionalHttpContext().Request, packages, searchTerm, targetFramework, includePrerelease, curatedFeed : null, semVerLevel : semVerLevel); // Packages provided by search service (even when not hijacked) var query = searchAdaptorResult.Packages; var semVerLevelKey = SemVerLevelKey.ForSemVerLevel(semVerLevel); // If intercepted, create a paged queryresult if (searchAdaptorResult.ResultsAreProvidedBySearchService) { // Add explicit Take() needed to limit search hijack result set size if $top is specified var totalHits = query.LongCount(); var pagedQueryable = query .Take(options.Top != null ? Math.Min(options.Top.Value, MaxPageSize) : MaxPageSize) .ToV2FeedPackageQuery( GetSiteRoot(), _configurationService.Features.FriendlyLicenses, semVerLevelKey); return(QueryResult(options, pagedQueryable, MaxPageSize, totalHits, (o, s, resultCount) => { // The nuget.exe 2.x list command does not like the next link at the bottom when a $top is passed. // Strip it of for backward compatibility. if (o.Top == null || (resultCount.HasValue && o.Top.Value >= resultCount.Value)) { return SearchAdaptor.GetNextLink(Request.RequestUri, resultCount, new { searchTerm, targetFramework, includePrerelease }, o, s); } return null; })); } //Reject only when try to reach database. if (!ODataQueryVerifier.AreODataOptionsAllowed(options, ODataQueryVerifier.V2Search, _configurationService.Current.IsODataFilterEnabled, nameof(Search))) { return(BadRequest(ODataQueryVerifier.GetValidationFailedMessage(options))); } // If not, just let OData handle things var queryable = query.ToV2FeedPackageQuery( GetSiteRoot(), _configurationService.Features.FriendlyLicenses, semVerLevelKey); return(QueryResult(options, queryable, MaxPageSize)); }