You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于HttpClient调用文件转换API时,如何仅返回status为successful的响应结果

Absolutely! You can add retry logic and status validation to your HttpClient call to only return the response when the status field is successful. Here's a robust implementation tailored to your scenario:

Handle File Conversion API with Retry Logic

The core idea is to check the status field in the response, retry when it's converting, and only return the result once it's marked successful. We'll also add safeguards to avoid infinite loops and improve reliability.

Step 1: Define Strongly-Typed Response Models

First, create C# classes to map the API response structure—this is far more maintainable than parsing raw JSON:

public class ConversionResponse
{
    [JsonPropertyName("id")]
    public int Id { get; set; }

    [JsonPropertyName("key")]
    public string ApiKey { get; set; }

    [JsonPropertyName("status")]
    public string Status { get; set; }

    [JsonPropertyName("sandbox")]
    public bool IsSandbox { get; set; }

    [JsonPropertyName("created_at")]
    public DateTime CreatedAt { get; set; }

    [JsonPropertyName("finished_at")]
    public DateTime FinishedAt { get; set; }

    [JsonPropertyName("source_file")]
    public FileDetails SourceFile { get; set; }

    [JsonPropertyName("target_files")]
    public List<FileDetails> TargetFiles { get; set; }

    [JsonPropertyName("target_format")]
    public string TargetFormat { get; set; }

    [JsonPropertyName("credit_cost")]
    public int CreditCost { get; set; }
}

public class FileDetails
{
    [JsonPropertyName("id")]
    public int Id { get; set; }

    [JsonPropertyName("name")]
    public string Name { get; set; }

    [JsonPropertyName("size")]
    public int Size { get; set; }
}

Step 2: Implement the Retry-Aware API Call

Modify your original code to include status checks and retry logic with reasonable limits:

// Configure these values based on your API's typical conversion speed
private const int MaxRetryAttempts = 25;
private const int RetryDelayMs = 4000; // Wait 4 seconds between retries

public async Task<ConversionResponse> GetCompletedConversionResult(string apiUrl, string apiKey)
{
    // Reuse HttpClient (better practice than creating a new one each time)
    using var handler = new HttpClientHandler { Credentials = new NetworkCredential(apiKey, "") };
    using var client = new HttpClient(handler);
    client.Timeout = TimeSpan.FromSeconds(75); // Avoid infinite timeouts

    for (int attempt = 0; attempt < MaxRetryAttempts; attempt++)
    {
        var request = new HttpRequestMessage(HttpMethod.Get, apiUrl);
        using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
        
        // First, ensure the HTTP request itself succeeded
        response.EnsureSuccessStatusCode();

        // Read and parse the response
        using var responseStream = await response.Content.ReadAsStreamAsync();
        using var reader = new StreamReader(responseStream);
        var jsonContent = await reader.ReadToEndAsync();
        var conversionResult = JsonSerializer.Deserialize<ConversionResponse>(jsonContent);

        // Handle different statuses
        if (conversionResult?.Status.Equals("successful", StringComparison.OrdinalIgnoreCase) == true)
        {
            // Optional: Validate target files exist as expected
            if (conversionResult.TargetFiles?.Any(file => !string.IsNullOrEmpty(file.Name)) != true)
            {
                throw new InvalidOperationException("Conversion marked successful but no valid target files found.");
            }
            return conversionResult;
        }
        else if (conversionResult?.Status.Equals("converting", StringComparison.OrdinalIgnoreCase) == true)
        {
            // Still converting—wait and retry
            await Task.Delay(RetryDelayMs);
            continue;
        }
        else
        {
            // Handle unexpected statuses (e.g., "failed")
            throw new InvalidOperationException($"Conversion failed with status: {conversionResult?.Status ?? "unknown"}");
        }
    }

    // Exceeded max retries without success
    throw new TimeoutException($"Conversion did not complete after {MaxRetryAttempts} attempts.");
}

Key Improvements & Notes

  • Strongly-Typed Parsing: Avoids messy raw JSON handling and catches typos at compile time.
  • Controlled Retries: Limits the number of attempts and adds a delay to avoid overwhelming the API. Adjust MaxRetryAttempts and RetryDelayMs based on how long your files typically take to convert.
  • Safe HttpClient Usage: While we use using here for simplicity, in production consider using IHttpClientFactory to reuse HttpClient instances and prevent socket exhaustion.
  • Timeout Protection: Replaces Timeout.Infinite with a reasonable timeout to prevent hanging requests.
  • Explicit Error Handling: Throws clear exceptions for failed conversions or missing files, making it easier to debug upstream issues.

Bonus Tip

If the API supports webhooks, consider using that instead of polling. You can register a webhook URL with the API, and it will send a notification when the conversion completes—this is more efficient than repeated GET requests.

内容的提问来源于stack exchange,提问作者Matteo Pietro Peru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 13:04:10