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

PHP Curl转.NET HttpRequest:多CSV文件带Token上传问题

Let's tackle this problem head-on. You're trying to convert a PHP cURL script for token-authenticated CSV uploads to C#, but ran into issues with WebClient's redirect loop and aren't sure if your RestClient implementation is correct. Here's how to fix everything:

Step 1: Verify Token Matching with PHP Script

First, let's confirm your token is being passed the same way as the PHP script. Assuming your PHP code looks like this (standard for token auth):

$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer YOUR_TOKEN_HERE"
]);
// ... rest of upload logic

Your C# code must mirror this header exactly. If the PHP script uses a custom header (e.g., X-Auth-Token), adjust your C# headers to match—this is critical for authentication to work.

Step 2: Fix WebClient's "Too Many Redirects" Error

The "Too many automatic redirections were attempted" error usually happens because:

  • The server is sending a circular redirect (e.g., HTTP → HTTPS → HTTP repeatedly)
  • WebClient's default redirect limit is hit (it's lower than you might expect)

Quick Fixes for WebClient:

  1. Disable auto-redirect and handle manually:
    webClient.AllowAutoRedirect = false;
    
    Then catch WebException and check for 3xx status codes to follow the redirect URL manually.
  2. Use the correct protocol: Double-check if your upload URL should use https:// instead of http://—many servers force HTTPS and redirect repeatedly if you use HTTP.
  3. Switch to HttpClient: WebClient is legacy; HttpClient has better redirect handling and is the recommended approach for .NET now.
Step 3: Correct C# Implementations

Let's walk through the recommended HttpClient approach, plus a valid RestClient implementation, and a fixed WebClient version.

This is the modern, maintainable way to handle HTTP requests in .NET:

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

class CsvUploader
{
    static async Task Main(string[] args)
    {
        var authToken = "YOUR_AUTH_TOKEN";
        var uploadEndpoint = "https://your-server.com/upload";

        // Reuse HttpClient (don't create a new instance every time!)
        using var httpClient = new HttpClient();
        
        // Add token header to match PHP script
        httpClient.DefaultRequestHeaders.Authorization = 
            new AuthenticationHeaderValue("Bearer", authToken);

        // Build multipart form data (matches cURL's POSTFIELDS)
        using var formContent = new MultipartFormDataContent();

        // Add single CSV file
        var firstCsvPath = @"C:\data\file1.csv";
        var firstCsvBytes = await System.IO.File.ReadAllBytesAsync(firstCsvPath);
        var firstCsvContent = new ByteArrayContent(firstCsvBytes);
        firstCsvContent.Headers.ContentType = MediaTypeHeaderValue.Parse("text/csv");
        formContent.Add(firstCsvContent, "files", "file1.csv"); // "files" = form field name (match PHP!)

        // Add multiple CSV files (reuse the same field name)
        var secondCsvPath = @"C:\data\file2.csv";
        var secondCsvBytes = await System.IO.File.ReadAllBytesAsync(secondCsvPath);
        var secondCsvContent = new ByteArrayContent(secondCsvBytes);
        secondCsvContent.Headers.ContentType = MediaTypeHeaderValue.Parse("text/csv");
        formContent.Add(secondCsvContent, "files", "file2.csv");

        try
        {
            var response = await httpClient.PostAsync(uploadEndpoint, formContent);
            response.EnsureSuccessStatusCode(); // Throws if status code is 4xx/5xx

            var responseBody = await response.Content.ReadAsStringAsync();
            Console.WriteLine($"Upload succeeded! Response: {responseBody}");
        }
        catch (HttpRequestException ex)
        {
            Console.WriteLine($"Upload failed: {ex.Message}");
        }
    }
}

Valid RestClient (RestSharp)

If you prefer RestSharp, make sure you're adding the token header and files correctly:

using RestSharp;
using System;

class RestSharpCsvUploader
{
    static void Main(string[] args)
    {
        var authToken = "YOUR_AUTH_TOKEN";
        var uploadEndpoint = "https://your-server.com/upload";

        var client = new RestClient(uploadEndpoint);
        var request = new RestRequest(Method.POST);

        // Add token header (match PHP!)
        request.AddHeader("Authorization", $"Bearer {authToken}");

        // Add single/multiple files
        request.AddFile("files", @"C:\data\file1.csv", "text/csv");
        request.AddFile("files", @"C:\data\file2.csv", "text/csv");

        try
        {
            var response = client.Execute(request);
            if (response.IsSuccessful)
            {
                Console.WriteLine($"Upload succeeded! Response: {response.Content}");
            }
            else
            {
                Console.WriteLine($"Upload failed. Status: {response.StatusCode}, Error: {response.ErrorMessage}");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Upload failed: {ex.Message}");
        }
    }
}

Fixed WebClient Implementation

If you must use WebClient, here's how to handle multi-file uploads and fix redirects:

using System;
using System.Net;
using System.Text;

class WebClientCsvUploader
{
    static void Main(string[] args)
    {
        var authToken = "YOUR_AUTH_TOKEN";
        var uploadEndpoint = "https://your-server.com/upload";

        using var webClient = new WebClient();
        
        // Add token header
        webClient.Headers.Add("Authorization", $"Bearer {authToken}");
        
        // Fix redirect loop: disable auto-redirect (handle manually if needed)
        webClient.AllowAutoRedirect = false;

        try
        {
            var boundary = $"---------------------------{DateTime.Now.Ticks:x}";
            webClient.Headers.Add("Content-Type", $"multipart/form-data; boundary={boundary}");

            // Build multipart form data for multiple files
            var formBuilder = new StringBuilder();
            var filePaths = new[] { @"C:\data\file1.csv", @"C:\data\file2.csv" };
            
            foreach (var filePath in filePaths)
            {
                var fileName = System.IO.Path.GetFileName(filePath);
                formBuilder.AppendLine($"--{boundary}");
                formBuilder.AppendLine($"Content-Disposition: form-data; name=\"files\"; filename=\"{fileName}\"");
                formBuilder.AppendLine("Content-Type: text/csv");
                formBuilder.AppendLine();
                formBuilder.AppendLine(System.IO.File.ReadAllText(filePath));
            }
            formBuilder.AppendLine($"--{boundary}--");

            var responseBytes = webClient.UploadData(uploadEndpoint, "POST", Encoding.UTF8.GetBytes(formBuilder.ToString()));
            var response = Encoding.UTF8.GetString(responseBytes);
            Console.WriteLine($"Upload succeeded! Response: {response}");
        }
        catch (WebException ex)
        {
            Console.WriteLine($"Upload failed: {ex.Message}");
            if (ex.Response is HttpWebResponse response)
            {
                Console.WriteLine($"Status Code: {response.StatusCode}");
                // Handle redirect manually if needed
                if (response.StatusCode is HttpStatusCode.Redirect or HttpStatusCode.MovedPermanently)
                {
                    var newUrl = response.Headers["Location"];
                    Console.WriteLine($"Redirecting to: {newUrl}");
                    // Repeat upload logic for newUrl here
                }
            }
        }
    }
}
Key Checks to Ensure Success
  • Header Match: Confirm your C# token header is identical to the PHP script (e.g., Authorization: Bearer XYZ vs custom headers like X-Auth-Token).
  • Form Field Name: The field name used for files (e.g., "files") must match what the server expects—this is set in the PHP CURLFile key.
  • Protocol: Use https:// if your server enforces it to avoid unnecessary redirects.

内容的提问来源于stack exchange,提问作者user5407401

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:50:44