public void QueryString_should_contain_existing_and_added_query_param() { var uri = new Uri("http://localhost/?param1=value1"); uri = uri.AddParameter("newParam", "newValue"); uri.Query.Should().Be("?param1=value1&newParam=newValue"); }
public void QueryString_should_omit_missing_value() { var uri = new Uri("http://localhost/"); uri = uri.AddParameter("newParam"); uri.Query.Should().Be("?newParam"); }
public void QueryString_should_contain_query_param() { var uri = new Uri("http://localhost/"); uri = uri.AddParameter("newParam", "newValue"); uri.Query.Should().Be("?newParam=newValue"); }
public async Task <SearchResultModel> SearchTitle(string titleText) { Uri uri = new Uri("https://eksisozluk.com/"); uri = uri.AddParameter("q", titleText); var request = new HttpRequestMessage() { RequestUri = uri, Method = HttpMethod.Get, }; // TODO : @deniz geçici olarak yapıldı. Nested tipleri handle edilen yapı oluşturulduğunda değiştirilecek using (HttpClient httpClient = new HttpClient()) { using (HttpResponseMessage httpResponseMessage = await httpClient.SendAsync(request)) { string htmlContent = await httpResponseMessage.Content.ReadAsStringAsync(); SearchResultModel searchResultModel = new SearchResultModel(); if (httpResponseMessage.StatusCode == HttpStatusCode.OK) { string titleNameIdText = httpResponseMessage.RequestMessage.RequestUri.AbsolutePath; TitleModel titleModel = _bindingComponent .Binder() .BindModelHtmlContent <TitleModel>(htmlContent, model => model.TitleNameIdText = titleNameIdText) .FirstOrDefault(); titleModel = titleModel ?? new TitleModel() { CurrentPage = "1", PageCount = "1", TitleNameIdText = titleNameIdText }; titleModel.EntryDetailModels = _bindingComponent .Binder() .BindModelHtmlContent <EntryDetailModel>(htmlContent, c => c.Content = c.Content.FixLinks()) .ToList(); searchResultModel.TitleModel = titleModel; searchResultModel.Result = true; return(searchResultModel); } searchResultModel.SuggestedTitleModels = _bindingComponent .Binder() .BindModelHtmlContent <SuggestedTitleModel>(htmlContent).ToList(); return(searchResultModel); } } }
public async Task <TitleModel> GetTitle(string titleNameIdText, bool?populer = null, int?page = null) { Uri uri = new Uri($"https://eksisozluk.com/{titleNameIdText}"); int currentPage = page ?? 1; if (populer.HasValue) { uri = uri.AddParameter("a", "popular"); } uri = uri.AddParameter("p", currentPage.ToString()); var request = new HttpRequestMessage() { RequestUri = uri, Method = HttpMethod.Get, }; request.Headers.Add("X-Requested-With", "XMLHttpRequest"); // TODO : @deniz nested modeller için binding desteklememiz gerekiyor. return(await BindHttpRequestMessage(request, htmlContent => { TitleModel titleModel = _bindingComponent .Binder() .BindModelHtmlContent <TitleModel>(htmlContent, model => model.TitleNameIdText = titleNameIdText) .FirstOrDefault(); titleModel = titleModel ?? new TitleModel() { CurrentPage = "1", PageCount = "1", TitleNameIdText = titleNameIdText }; titleModel.EntryDetailModels = _bindingComponent .Binder() .BindModelHtmlContent <EntryDetailModel>(htmlContent, t => t.Content = t.Content.FixLinks()).ToList(); return titleModel; })); }
private Uri GenerateUri <TParams>( ILacrmFunction <TParams> function) where TParams : Parameter { var param = JsonSerializer.Serialize(function.Parameters, _opt); return(_baseAddress.AddParameter(Function, function.Function) .AddParameter(Parameters, param)); }
public static Uri AddParameterString(this Uri uri, string key, string value) { if (string.IsNullOrEmpty(value)) { return(uri); } else { return(uri.AddParameter(key, value)); } }
public static MvcHtmlString RenderCaptchaScript(this HtmlHelper helper) { var captchaScriptTag = new TagBuilder("script"); var scriptSrcUri = new Uri("https://www.google.com/recaptcha/api.js"); scriptSrcUri.AddParameter(CaptchaConstraints.OnloadCallback, GoogleCaptchaConfiguration.OnLoadCallback); scriptSrcUri.AddParameter(CaptchaConstraints.Language, GoogleCaptchaConfiguration.Language); scriptSrcUri.AddParameter(CaptchaConstraints.Render, GoogleCaptchaConfiguration.Render); captchaScriptTag.Attributes.Add("src", scriptSrcUri.ToString()); captchaScriptTag.Attributes.Add("async", string.Empty); captchaScriptTag.Attributes.Add("defer", string.Empty); return(MvcHtmlString.Create(captchaScriptTag.ToString())); }
public void AddParameter_NullEmptyWhitespaceArguments_ArgumentNullException() { // Arrange Uri uri = null; ArgumentNullException ex; // Act / Assert ex = Assert.Throws <ArgumentNullException>(() => uri.AddParameter("foo", "bar")); Assert.Equal(nameof(uri), ex.ParamName); uri = new Uri("http://domain.com"); ex = Assert.Throws <ArgumentNullException>(() => uri.AddParameter(null, "bar")); Assert.Equal("name", ex.ParamName); ex = Assert.Throws <ArgumentNullException>(() => uri.AddParameter(string.Empty, "bar")); Assert.Equal("name", ex.ParamName); ex = Assert.Throws <ArgumentNullException>(() => uri.AddParameter(" ", "bar")); Assert.Equal("name", ex.ParamName); }
private void bSearch_Click(object sender, EventArgs e) { using (WebClient webClient = new WebClient()) { var uri = new Uri($@"http://www.omdbapi.com/?apikey=dbf23902"); uri = uri.AddParameter("t", tbSearch.Text); var data = webClient.DownloadString(uri); //richTextBox1.Text = data; //tbSearch.Text = data; dynamic obj = JObject.Parse(data); //richTextBox1.Text = obj.Title; if (obj.Response == "False") { MessageBox.Show((string)obj.Error); return; } if (!File.Exists(@"pics\")) { Directory.CreateDirectory(@"pics\"); } if (obj.Poster != "N/A") { webClient.DownloadFile((string)obj.Poster, $@"pics\{obj.imdbID}.jpg"); pbSearchResult.Image = Image.FromFile($@"pics\{obj.imdbID}.jpg"); tbPicPath.Text = Application.ExecutablePath; int length = tbPicPath.Text.Length; tbPicPath.Text = tbPicPath.Text.Remove(length - 13); tbPicPath.Text += "pics\\" + obj.imdbID + ".jpg"; } tBTitle.Text = obj.Title; mtBYear.Text = "0"; if (obj.Year != "N/A") { mtBYear.Text = obj.Year; } mtBRuntime.Text = "0"; if (obj.Runtime != "N/A") { mtBRuntime.Text = obj.Runtime; } cBGenre.Text = obj.Genre; cBLanguage.Text = obj.Language; tBDirector.Text = obj.Director; rTBDescription.Text = obj.Plot; } }
public void AddParameter_ValidValues_Success(string adress, string name, string value, string expectedAdress) { // Arrange var request = new Uri(adress); // Act var newRequest = request.AddParameter(name, value); // Assert Assert.Equal(expectedAdress, newRequest.ToString()); }
public static Uri AddCredentials(this Uri uri, Credentials credentials) { if (String.IsNullOrEmpty(credentials.ClientId) ^ String.IsNullOrEmpty(credentials.PrivateKey)) { throw new GoogleMapsException("Credentials must specify both ClientId and PrivateKey"); } if (!String.IsNullOrEmpty(credentials.PrivateKey) && !String.IsNullOrEmpty(credentials.ApiKey)) { throw new GoogleMapsException("Credentials should be either an ApiKey or a ClientId / PrivateKey pair"); } if (!String.IsNullOrEmpty(credentials.ApiKey)) { return(uri.AddParameter("key", credentials.ApiKey)); } else if (!String.IsNullOrEmpty(credentials.ClientId)) { return(uri.AddParameter("client", credentials.ClientId).AddSignature(credentials.PrivateKey)); } // No credentials were provided return(uri); }
public static string EncodeHTTPBinding(Uri uri, XmlElement obj, string samlName, string relayState, X509Certificate2 certificate, SignatureAlgorithms?sigAlg) { var dic = Encode(obj, samlName, relayState); if (sigAlg != null) { dic.Add("SigAlg", Constants.MappingDigestMethodToStr[sigAlg.Value]); } foreach (var kvp in dic) { uri = uri.AddParameter(kvp.Key, kvp.Value); } if (sigAlg != null) { var prk = certificate.PrivateKey as RSA; var hashed = Hash.Compute(uri.Query.TrimStart('?'), sigAlg.Value); var signed = prk.SignHash(hashed, Constants.MappingSignatureAlgToHash[sigAlg.Value], RSASignaturePadding.Pkcs1); uri = uri.AddParameter("Signature", Convert.ToBase64String(signed)); } return(uri.ToString()); }
public async static Task <List <FavoritedBillInfo> > FavoritedBills(int userid, string account_No) { Uri unsettleURI = FavoritedBillsURI.AddParameter("userId", userid.ToString()); Uri settleURI = unsettleURI.AddParameter("accountNo", account_No); string response = await Client.GetStringAsync(settleURI); if (response != null) { Dictionary <string, object> data = JsonConvert.DeserializeObject <Dictionary <string, object> >(response); var Favbills = JsonConvert.DeserializeObject <List <FavoritedBillInfo> >(data["FavoritedBills"].ToString()); return(Favbills); } return(null); }
public void QueryString_should_add_many_parameters() { var uri = new Uri("http://localhost/"); var parameters = new System.Collections.Generic.Dictionary <string, string>() { ["newParam1"] = "newValue1", ["newParam2"] = "newValue2", ["newParam3"] = "newValue3", ["newParam4"] = "newValue4", ["newParam5"] = "newValue5", }; uri = uri.AddParameter(parameters); uri.Query.Should().Be("?newParam1=newValue1&newParam2=newValue2&newParam3=newValue3&newParam4=newValue4&newParam5=newValue5"); }
public async Task <PopulerModel> GetPopulerList(int?page = null) { Uri uri = new Uri("https://eksisozluk.com/basliklar/populer"); int currentPage = page ?? 1; uri = uri.AddParameter("_", DateTime.Now.Ticks.ToString()) .AddParameter("p", currentPage.ToString()); var request = new HttpRequestMessage() { RequestUri = uri, Method = HttpMethod.Get, }; request.Headers.Add("X-Requested-With", "XMLHttpRequest"); return(await BindHttpRequestMessage(request, htmlContent => { List <PopulerTitleHeaderModel> populerTitleHeaderModels = _bindingComponent .Binder() .BindModelHtmlContent <PopulerTitleHeaderModel>(htmlContent, model => { model.Title = model.Title.Substring(0, model.Title.Length - model.EntryCount.Length); }).ToList(); PopulerModel populerModel = _bindingComponent .Binder() .BindModelHtmlContent <PopulerModel>(htmlContent).FirstOrDefault(); // Pager ilk sayfada gelmiyor. 2. sayfadan itibaren geliyor. populerModel = populerModel ?? new PopulerModel() { CurrentPage = "1", PageCount = "2" }; populerModel.PopulerTitleHeaderModels = populerTitleHeaderModels; return populerModel; })); }
static Uri AddSignature(this Uri uri, string privateKey) { var encoding = new ASCIIEncoding(); // converting key to bytes will throw an exception, need to replace '-' and '_' characters first. string usablePrivateKey = privateKey.Replace("-", "+").Replace("_", "/"); var privateKeyBytes = Convert.FromBase64String(usablePrivateKey); var encodedPathAndQueryBytes = encoding.GetBytes(uri.LocalPath + uri.Query); // compute the hash var algorithm = new HMACSHA1(privateKeyBytes); var hash = algorithm.ComputeHash(encodedPathAndQueryBytes); // convert the bytes to string and make url-safe by replacing '+' and '/' characters var signature = Convert.ToBase64String(hash).Replace("+", "-").Replace("/", "_"); // Add the signature to the existing URI. return(uri.AddParameter("signature", signature)); }
public async Task <CharacterSearchResultModel[]> SearchCharactersAsync(string name) { using (var webView = Api.Create.HttpClientWebView()) { var searchString = name.Replace(" ", "+"); var searchBaseUri = new Uri($"https://eu.finalfantasyxiv.com/lodestone/community/search"); var searchUri = searchBaseUri .AddParameter("q", searchString) .AddParameter("timezone_info", @"{""today"":{""method"":""point"",""epoch"":1509228000,""year"":2017,""month"":10,""date"":29}}") .AddParameter("_", "1509292185491"); await Task.Run(() => webView.NavigateAsync(searchUri)); var divs = webView.Nodes().Divs().ToArray(); var characterAnchors = webView.Nodes().Divs().Where( ).Classes("frame__chara__box").Select(p => p.Parent).ToArray(); return(characterAnchors.Select(a => new CharacterSearchResultModel(a)).ToArray()); } }
/// <summary> /// Remove a like on this media by the currently authenticated user. /// Required scope: likes /// </summary> /// <param name="accessToken" type="string"> /// <para> /// A valid access token. /// </para> /// </param> public async Task<string> DeleteLikeAsync(string mediaId, string accessToken) { using (HttpClient httpClient = new HttpClient()) { Uri uri = LikeEndpointsUrlsFactory.CreateDELETELikeUrl(mediaId, accessToken); if (this.EnforceSignedRequests) { uri = uri.AddParameter("sig", Utilities.GenerateSig(string.Format(InstagramAPIEndpoints.LikesEndpoint, mediaId), this.ClientSecret, uri.Query)); } var response = await httpClient.DeleteAsync(uri); string responseContent = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { return responseContent; } else { throw new InstagramAPIException(responseContent); } } }
public static string[] GetData(string title) { using (WebClient webClient = new WebClient()) { try { Link = Link.AddParameter("t", title); var data = Encoding.UTF8.GetString(webClient.DownloadData(Link)); dynamic obj = JObject.Parse(data); if (obj.Response == "False") { throw new ArgumentException(obj.Error); } string[] Data = { obj.Title, obj.Genre, obj.Type, obj.Runtime, obj.Year, obj.Poster }; return(Data); } catch (Exception) { throw; } } }
/// <summary> /// This endpoint returns the same response as GET /media/media-id. /// A media object's shortcode can be found in its shortlink URL. /// An example shortlink is http://instagram.com/p/tsxp1hhQTG/. /// Its corresponding shortcode is tsxp1hhQTG. /// </summary> /// <param name="shortCode">shortCode</param> /// <param name="accessToken" type="string"> /// <para> /// A valid access token. /// </para> /// </param> public async Task <string> GetMediaInfoByShortCodeAsync(string shortCode, string accessToken) { using (HttpClient httpClient = new HttpClient()) { Uri uri = MediaEndpointsUrlsFactory.CreateShortCodeMediaInfoUrl(shortCode, accessToken); if (this.EnforceSignedRequests) { uri = uri.AddParameter("sig", Utilities.GenerateSig(string.Format(InstagramAPIEndpoints.ShortCodeMediaInfoEndpoint, shortCode), this.ClientSecret, uri.Query)); } var response = await httpClient.GetAsync(uri); string responseContent = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { return(responseContent); } else { throw new InstagramAPIException(responseContent); } } }
/// <summary> /// Search for recent media in a given area. /// </summary> /// <param name="accessToken" type="string"> /// <para> /// A valid access token. /// </para> /// </param> /// <param name="distance">Default is 1km (distance=1000), max distance is 5km.</param> /// <param name="lat">Latitude of the center search coordinate. If used, lng is required.</param> /// <param name="lng">Longitude of the center search coordinate. If used, lat is required.</param> /// <returns>JSON result string.</returns> public async Task <string> SearchMediaAsync(string accessToken, double distance = 1000, double lat = 0, double lng = 0) { using (HttpClient httpClient = new HttpClient()) { Uri uri = MediaEndpointsUrlsFactory.CreateSearchMediaUrl(accessToken, distance, lat, lng); if (this.EnforceSignedRequests) { uri = uri.AddParameter("sig", Utilities.GenerateSig(InstagramAPIEndpoints.SearchMediaEndpoint, this.ClientSecret, uri.Query)); } var response = await httpClient.GetAsync(uri); string responseContent = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { return(responseContent); } else { throw new InstagramAPIException(responseContent); } } }
/// <summary> /// Get a list of recently tagged media. Note that this media is ordered by when the media was tagged with this tag, rather than the order it was posted. Use the max_tag_id and min_tag_id parameters in the pagination response to paginate through these objects. /// Can return a mix of image and video types. /// </summary> /// <param name="accessToken" type="string"> /// <para> /// A valid access token. /// </para> /// </param> /// <param name="minId">Return media before this min_id.</param> /// <param name="maxId">Return media after this max_id.</param> /// <returns>JSON result string.</returns> public async Task <string> GetRecentTaggedMediaAsync(string tagName, string accessToken, int count = 0, string minTagId = null, string maxTagId = null) { using (HttpClient httpClient = new HttpClient()) { Uri uri = TagEndpointsUrlsFactory.CreateRecentTaggedMediaUrl(tagName, accessToken, count, minTagId, maxTagId); if (this.EnforceSignedRequests) { uri = uri.AddParameter("sig", Utilities.GenerateSig(string.Format(InstagramAPIEndpoints.RecentTaggedMediaEndpoint, tagName), this.ClientSecret, uri.Query)); } var response = await httpClient.GetAsync(uri); string responseContent = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { return(responseContent); } else { throw new InstagramAPIException(responseContent); } } }
/// <summary> /// Modify the relationship between the current user and the target user. /// Required scope: relationships. /// </summary> /// <param name="relationshipAction">One of follow/unfollow/block/unblock/approve/deny.</param> public async Task <string> PostRelationshipActionAsync(long userId, string accessToken, RelationshipActions relationshipAction) { using (HttpClient httpClient = new HttpClient()) { Uri uri = RelationshipEndpointUrlsFactory.CreatePOSTRelationshipActionUrl(userId, accessToken, relationshipAction); if (this.EnforceSignedRequests) { uri = uri.AddParameter("sig", Utilities.GenerateSig(string.Format(InstagramAPIEndpoints.RelationshipEndpoint, userId), this.ClientSecret, uri.Query)); } var response = await httpClient.PostAsync(uri, null); string responseContent = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { return(responseContent); } else { throw new InstagramAPIException(responseContent); } } }
/// <summary> /// Get the list of users this user follows. /// Required scope: relationships. /// </summary> /// <returns>JSON result string.</returns> public async Task <string> GetFollowsAsync(string accessToken) { using (HttpClient httpClient = new HttpClient()) { Uri uri = RelationshipEndpointUrlsFactory.CreateUserFollowsUrl(accessToken); if (this.EnforceSignedRequests) { uri = uri.AddParameter("sig", Utilities.GenerateSig(InstagramAPIEndpoints.UserFollowedByEndpoint, this.ClientSecret, uri.Query)); } var response = await httpClient.GetAsync(uri); string responseContent = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { return(responseContent); } else { throw new InstagramAPIException(responseContent); } } }
/// <summary> /// Get the most recent media published by a user. May return a mix of both image and video types. /// </summary> /// <param name="count">Count of media to return.</param> /// <param name="accessToken">A valid access token.</param> /// <param name="minId">Return media later than this min_id.</param> /// <param name="maxId">Return media earlier than this max_id.</param> /// <param name="minTimestamp">Return media after this UNIX timestamp.</param> /// <param name="maxTimestamp">Return media before this UNIX timestamp.</param> /// <returns>JSON result string.</returns> public async Task <string> GetUserRecentMediaAsync(long userId, string accessToken, int count = 0, string minId = null, string maxId = null, long minTimestamp = 0, long maxTimestamp = 0) { using (HttpClient httpClient = new HttpClient()) { Uri uri = UserEndpointUrlsFactory.CreateUserRecentMediaUrl(userId, accessToken, count, minId, maxId, minTimestamp, maxTimestamp); if (this.EnforceSignedRequests) { uri = uri.AddParameter("sig", Utilities.GenerateSig(string.Format(InstagramAPIEndpoints.UserRecentMediaEndpoint, userId), this.ClientSecret, uri.Query)); } var response = await httpClient.GetAsync(uri); string responseContent = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { return(responseContent); } else { throw new InstagramAPIException(responseContent); } } }
public async Task <ApplicationTestResponse> SendAuthCallback(Application application, string requestId, string result, string openPlatformsUserId) { try { Validate(application, requestId, result, openPlatformsUserId); } catch (Exception ex) { return(new ApplicationTestResponse { StatusCode = System.Net.HttpStatusCode.BadRequest, Success = false, TestedUrl = "", Message = ex.Message }); } var uri = new Uri(application.AuthCallbackUrl); uri = uri.AddParameter(nameof(requestId), requestId) .AddParameter(nameof(result), result) .AddParameter(nameof(openPlatformsUserId), openPlatformsUserId) ; return(await SendGetToApplication(uri)); }
async public static Task <AccountInfo> GetAccounts(string accountNo, string serialNo) { Uri firstURI = AccountsURI.AddParameter("accountNo", accountNo); Uri settleURI = firstURI.AddParameter("serialNo", serialNo); string response = await Client.GetStringAsync(settleURI); if (response != null) { Dictionary <string, object> data = JsonConvert.DeserializeObject <Dictionary <string, object> >(response); if (data["Status"].ToString() == "404") { Console.WriteLine(data["Message"]); return(null); } AccountInfo AccountInfo = JsonConvert.DeserializeObject <AccountInfo>(data["AccountInfo"].ToString()); return(AccountInfo); } return(null); }
protected async Task <T> SendAsync <T>( HttpMethod method, string endpoint, Dictionary <string, string> parameters = null, bool useGlobalMobileApiV1 = false, string profileId = null) where T : class { T obj; try { await this._configurationService.InitAsync(); Uri uri = new Uri(new Uri(!useGlobalMobileApiV1 || ConfigurationRepository.EnvironmentSetting.Environment != Ekreta.Mobile.Core.Models.Environments.Environments.PROD ? ConfigurationRepository.EnvironmentSetting.GlobalMobileApiUrl : "https://kretaglobalmobileapi.ekreta.hu"), string.Format("api/v2/" + endpoint)); if (parameters != null) { foreach (KeyValuePair <string, string> parameter in parameters) { string str = WebUtility.UrlEncode(parameter.Value); uri = uri.AddParameter(parameter.Key, str); } } HttpRequestMessage httpRequestMessage = new HttpRequestMessage(method, uri); httpRequestMessage.Headers.Add("Accept", "application/json"); httpRequestMessage.Headers.Add("apiKey", ConfigurationRepository.EnvironmentSetting.ConfigurationServiceApiKey); GlobalMobileApi.AddAccessTokenToHttpHeader <T>(httpRequestMessage, profileId); using (HttpClient httpClient = this.BuildHttpClient()) { int num1; int num2 = num1 - 1; try { HttpResponseMessage response = await httpClient.SendAsync(httpRequestMessage); if (response.IsSuccessStatusCode) { obj = (T)JsonConvert.DeserializeObject <T>(await response.Content.ReadAsStringAsync()); response = (HttpResponseMessage)null; } else { if (response.StatusCode == HttpStatusCode.NotFound) { throw new KeyNotFoundException(); } string str = await response.Content.ReadAsStringAsync(); throw new ServerUnreachableException(response); } } catch (Exception ex) { CrossMobileAnalytics.Current.TrackException(ex, (IDictionary <string, string>) new Dictionary <string, string>() { { "uri", uri.ToString() } }, nameof(SendAsync), "/Users/admin/myagent/macMiniBlack3/_work/2/s/eKreta.Mobile/eKreta.Mobile.Core.Standard/Services/GlobalMobileApi.cs", 205); throw; } } uri = (Uri)null; } catch (Exception ex) { CrossMobileAnalytics.Current.TrackException(ex, (IDictionary <string, string>)null, nameof(SendAsync), "/Users/admin/myagent/macMiniBlack3/_work/2/s/eKreta.Mobile/eKreta.Mobile.Core.Standard/Services/GlobalMobileApi.cs", 213); throw; } return(obj); }
async IAsyncEnumerable <ParsedImage> IImageParsingStrategy.ParseAsync(ParseRequest request, IProgress <ParseProgress> progress) { if (request is null) { ThrowHelper.ArgumentNull(nameof(request)); } if (request.EstimatedCount < 1) { ThrowHelper.ArgumentOutOfRange(nameof(request.EstimatedCount), request.EstimatedCount, "Value must be 1 or greater!"); } var imagesPerCategory = (double)request.EstimatedCount / request.Categories.Count(); var capacity = (int)Math.Ceiling(imagesPerCategory / _pageSize) * request.Categories.Sum(x => x.Keywords.Count()); var throttler = new SemaphoreSlim(MaxThreads); var currentCount = 0; foreach (var category in request.Categories) { var keywordsCount = category.Keywords.Count(); var imagesPerKeyword = (int)Math.Ceiling(imagesPerCategory / keywordsCount); var allTasks = new List <Task>(); var parsedImages = new List <ParsedImage>(imagesPerKeyword); var total = (int)Math.Ceiling((double)imagesPerKeyword / _pageSize); var pages = Enumerable.Range(_startFrom, total); var disposables = new List <IDisposable>(); foreach (var keyword in category.Keywords) { await throttler.WaitAsync(); allTasks.Add( Task.Run(async() => { try { var uri = new Uri(_url).AddParameter("query", keyword); foreach (var page in pages) { var pageUri = uri.AddParameter("per_page", _pageSize) .AddParameter("page", page); var take = imagesPerKeyword - (page - 1) * _pageSize; var response = await _httpClient.GetAsync <Response>(pageUri); disposables.Add(response.Disposable); var results = response.Result.Results.Take(take); foreach (var result in results) { var download = await _httpClient.GetAsync(result.Links.Download); var stream = await download.Content.ReadAsStreamAsync(); var image = Image.FromStream(stream); var parsedImage = new ParsedImage { Category = category.Name, Image = image, Keyword = keyword }; parsedImages.Add(parsedImage); disposables.Add(download); disposables.Add(stream); } } } finally { throttler.Release(); } })); } await Task.WhenAll(allTasks); foreach (var parsedImage in parsedImages) { var data = new ParseProgress { CurrentCount = ++currentCount, EstimatedCount = request.EstimatedCount }; progress?.Report(data); yield return(parsedImage); } foreach (var disposable in disposables) { disposable.Dispose(); } } }