Вызывайте solvethree из бэкенда ASP.NET Core
Зарегистрируйте типизированный HttpClient, создайте задачу один раз, затем запрашивайте её статус в пределах заданного срока. Храните API-ключ на сервере и защитите все маршруты приложения, вызывающие клиент.
Пример ниже — вспомогательный REST-клиент для reCAPTCHA Enterprise, а не официальный C# SDK. Создание и получение задачи разделены, поэтому приложению не нужно держать один входящий запрос открытым до завершения решения.
На этой странице
Зарегистрируйте типизированный клиент
Сначала активируйте в консоли профиль целевого сайта для своего рабочего пространства. Отправка имени хоста и действия не создаст профиль. Если сайт ещё не настроен, см. настройку профиля сайта.
Поместите ключ рабочего пространства в серверную конфигурацию как SOLVETHREE_API_KEY. Добавьте класс клиента, затем раскомментируйте регистрацию, показанную в разделе Program.cs, и разместите её перед builder.Build().
// CaptchaClient.cs; .NET 8+, System.Net.Http.Json and System.Text.Json.Nodes.
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json.Nodes;
public sealed class CaptchaClient(HttpClient http)
{
public async Task<JsonObject> CreateAsync(string site, string proxy, string requestId,
CancellationToken cancellationToken)
{
using var response = await http.PostAsJsonAsync("tasks?waitMs=0",
new { site, action = "login", proxy, requestId }, cancellationToken);
response.EnsureSuccessStatusCode();
return (await response.Content.ReadFromJsonAsync<JsonObject>(cancellationToken))!;
}
public async Task<JsonObject> GetAsync(string id, CancellationToken cancellationToken)
{
using var response = await http.GetAsync("tasks/" + Uri.EscapeDataString(id) + "?waitMs=15000",
cancellationToken);
response.EnsureSuccessStatusCode();
return (await response.Content.ReadFromJsonAsync<JsonObject>(cancellationToken))!;
}
}
// Program.cs, before builder.Build(), in an existing authenticated ASP.NET app:
// builder.Services.AddHttpClient<CaptchaClient>(http => {
// http.BaseAddress = new Uri("https://api.solvethree.com/v1/");
// http.Timeout = TimeSpan.FromSeconds(25);
// http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
// "Bearer", builder.Configuration["SOLVETHREE_API_KEY"]
// ?? throw new InvalidOperationException("Missing API key"));
// }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler {
// AllowAutoRedirect = false
// });
// Inject CaptchaClient into your authenticated controller/service. Pass its
// cancellation token, create once, save id and poll GetAsync with a finite deadline.Регистрация задаёт базовый адрес API, аутентификацию Bearer и транспортный тайм-аут 25 секунд, а также отключает автоматические перенаправления. Сохраните завершающий слеш в базовом адресе: относительные пути клиента tasks должны разрешаться внутри /v1/.
Вспомогательный класс использует JSON-расширения HttpClient и возвращает JsonObject. Оба метода проверяют успешность HTTP-ответа перед десериализацией. Внедрите CaptchaClient в контроллер или сервис с проверкой аутентификации; сам вспомогательный класс не выполняет аутентификацию или авторизацию вызывающих ваше приложение клиентов.
Создайте задачу один раз и сохраните данные для восстановления
- 1.
Выберите сайт, действие и прокси
Передавайте в site имя целевого хоста, а не полный URL. В этом примере action зафиксировано как login; замените его на действие, которое ожидает целевой ресурс. Пример отправляет один прокси и использует режим reCAPTCHA enterprise-v3 по умолчанию. Не добавляйте поля type или url.
- 2.
Сохраните requestId перед вызовом CreateAsync
Используйте 1–64 символа из букв ASCII, цифр, знаков подчёркивания или дефисов. Сохраните идентификатор вместе с точными входными данными задачи, чтобы восстановить ту же логическую задачу при потере ответа.
- 3.
Вызовите CreateAsync и сохраните полученный ID задачи
CreateAsync выполняет один POST-запрос с waitMs=0. Передайте CancellationToken вызывающей стороны. Получив ID задачи, используйте GetAsync для её получения, а не создавайте новую.
Разрешайте расходовать средства рабочего пространства только после проверок авторизации в приложении. Если эти значения поступают во входящем запросе, проверяйте, разрешено ли вызывающей стороне использовать запрошенные сайт, действие и прокси.
Ограничьте общее время опроса
GetAsync экранирует известный ID задачи и запрашивает waitMs=15000. Тайм-аут HttpClient в 25 секунд ограничивает каждый HTTP-запрос, но не общее время, которое приложение тратит на опрос. Задайте отдельный общий предельный срок и передавайте отмену в каждый вызов.
pendingилиsolving: продолжайте, только пока это допускают предельный срок опроса и сигнал отмены вызывающей стороны.ready: прекратите опрос и прочитайте решение. Только этот статус содержит пригодное к использованию решение.failed: прекратите опрос и проверьтеerrorCodeиerror.
В приложении с браузерным интерфейсом сделайте создание и последующие проверки статуса отдельными защищёнными операциями вместо цикла внутри одного входящего запроса до завершения задачи. Сохраняйте ID задачи по истечении локального предельного срока, чтобы последующий авторизованный запрос мог получить её.
При отправке токена целевому ресурсу, для которого он предназначен, используйте возвращённые в решении параметры идентификации userAgent и secChUa, а также тот же прокси, который использовался для решения. Готовая задача означает, что решение получено, а не то, что запрос приложения выполнен успешно.
Восстановитесь после тайм-аута без дублирования работы
- CreateAsync завершается по тайм-ауту или отменяется до получения ID.
Сервер уже мог создать задачу. Локальная отмена не отменяет работу на сервере.
Попробуйте: Для восстановления повторно отправьте те же входные данные задачи с сохранённым requestId. При одинаковых ID и входных данных возвращается существующая задача; изменение входных данных при повторном использовании этого ID приводит к конфликту.
- GetAsync завершается по тайм-ауту или истекает предельный срок опроса.
У вас уже есть ID задачи, поэтому отсутствие ответа не требует создания замены.
Попробуйте: Сохраните ID и получите эту задачу позже в рамках новой операции с ограниченным временем выполнения.
- HTTP-вызов возвращает неуспешный ответ.
EnsureSuccessStatusCode выбрасывает исключение до того, как вспомогательный класс прочитает тело успешного ответа. Это отличается от получения задачи со статусом failed.
Попробуйте: Обработайте ошибку HTTP отдельно. Исправьте некорректные входные данные вместо повторной отправки без изменений.
- Задача переходит в статус failed.
Прочитайте errorCode и error, чтобы узнать причину ошибки задачи, например site-unreachable.
Попробуйте: Прекратите опрос этой задачи и устраните указанную причину, прежде чем запускать новое решение.
Используйте руководство по ошибкам API, чтобы отличить отклонённый запрос API от конечной ошибки решения.
Источники и справочник API
Запустите первую задачу.
Начните с $5 на балансе рабочего пространства.