使用C# WebRequest调用Voxbone REST API上传文件遇500错误求助
Troubleshooting 500 Internal Server Error When Uploading Address Proof via Voxbone REST API
Let's break down the issues in your code that are likely causing the request to fail before reaching Voxbone's system, and walk through fixes step by step.
Key Issues in Your Current Code
- Incorrect Boundary Format: Your
ContentTypeincludes an unnecessary space afterboundary=, and the boundary string in your multipart body doesn't follow proper formatting rules. Multipart boundaries must be consistent between the header and body with no extra spaces. - Invalid Multipart Structure: The multipart sections are missing required line breaks between the boundary, headers, and content. Voxbone's API expects strict
multipart/form-dataformatting, which requires empty lines to separate headers from their corresponding content. - File Handling Mistake: You're treating the file content as a plain string ("Wuppertal") instead of reading the actual binary file content. Additionally, converting the entire multipart body to Base64 is unnecessary—you should write raw bytes directly to the request stream.
- Variable Mismatch: You define
buffer3but try to writedatato the stream, which is an undefined variable, leading to a runtime error before the request even sends.
Corrected Code Example
Here's a revised version of your code that fixes these issues and properly constructs the multipart request:
using System; using System.IO; using System.Net; using System.Text; class VoxboneAddressUpload { static void Main(string[] args) { string apiUrl = "https://sandbox.voxbone.com/ws-voxbone/services/rest/regulation/address"; string method = "POST"; // Confirm this matches Voxbone's API requirements string boundary = $"----VoxboneFormBoundary{DateTime.Now.Ticks.ToString("x")}"; // Unique boundary to avoid conflicts // Initialize web request WebRequest myReq = WebRequest.Create(apiUrl); myReq.Method = method; myReq.ContentType = $"multipart/form-data; boundary={boundary}"; // Basic Authentication setup string username = "xxxxxx"; string password = "xxxxxx"; string authToken = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{password}")); myReq.Headers.Add("Authorization", $"Basic {authToken}"); // Build and write multipart content to request stream using (var reqStream = myReq.GetRequestStream()) { // 1. Add JSON payload section string jsonPayload = @" { ""salutation"" : ""MR"", ""companyName"" : null, ""companyDescription"" : null, ""firstName"" : ""rahul"", ""lastName"" : ""singh"", ""buildingNumber"" : ""23"", ""identityDocumentProof"" : { ""Nationality"" : ""IND"", ""identityDocumentType"" : ""NATIONAL_ID_CARD"", ""identityDocumentNumber"" : ""jfklajfljsdfl;dslfj"", ""issuingAuthority"" : ""jkhkjhkj"", ""issuingDate"" : ""2017-11-30"" }, ""extraFields"" : { ""Signatory date of birth"" : ""1993-01-05"", ""Signatory place of birth"" : ""varanasi,India"", ""Signatory tax code"" : ""dsdfsfsdf"" } }"; byte[] jsonBytes = Encoding.UTF8.GetBytes( $"--{boundary}\r\n" + "Content-ID: createRegulationAddressRequest\r\n" + "Content-Type: application/json\r\n\r\n" + // Empty line separates headers from content jsonPayload + "\r\n" ); reqStream.Write(jsonBytes, 0, jsonBytes.Length); // 2. Add file upload section (proofOfIdentityDocument) string filePath = @"C:\path\to\your\stripe.png"; // Replace with your actual file path if (File.Exists(filePath)) { byte[] fileContent = File.ReadAllBytes(filePath); byte[] fileHeader = Encoding.UTF8.GetBytes( $"--{boundary}\r\n" + "Content-ID: proofOfIdentityDocument\r\n" + "Content-Type: application/octet-stream\r\n" + "Content-Transfer-Encoding: binary\r\n" + $"Content-Disposition: file-data; name=\"proofOfIdentityDocument\"; filename=\"{Path.GetFileName(filePath)}\"\r\n\r\n" ); reqStream.Write(fileHeader, 0, fileHeader.Length); reqStream.Write(fileContent, 0, fileContent.Length); reqStream.Write(Encoding.UTF8.GetBytes("\r\n"), 0, 2); } else { throw new FileNotFoundException("Identity proof file not found.", filePath); } // Close the multipart request with final boundary byte[] endBoundary = Encoding.UTF8.GetBytes($"--{boundary}--\r\n"); reqStream.Write(endBoundary, 0, endBoundary.Length); } // Handle response and errors try { using (WebResponse wr = myReq.GetResponse()) using (Stream receiveStream = wr.GetResponseStream()) using (StreamReader reader = new StreamReader(receiveStream, Encoding.UTF8)) { string content = reader.ReadToEnd(); Console.WriteLine("API Response: " + content); } } catch (WebException ex) { if (ex.Response is HttpWebResponse errorResp) { Console.WriteLine($"Error Status: {(int)errorResp.StatusCode} - {errorResp.StatusDescription}"); using (StreamReader errorReader = new StreamReader(errorResp.GetResponseStream())) { Console.WriteLine("Error Details: " + errorReader.ReadToEnd()); } } else { Console.WriteLine("Request failed: " + ex.Message); } } } }
Additional Troubleshooting Steps
- Confirm HTTP Method: Double-check Voxbone's API documentation to ensure you're using the correct method (most upload endpoints use
POST). - Validate JSON Schema: Ensure your JSON payload matches all required fields and data types specified in Voxbone's regulation API docs.
- Test with Postman: Replicate the request in Postman first to confirm the API works with a properly formatted request, then mirror that structure in your code.
- Enable Request Logging: Add logging to capture the full request headers and body (redact sensitive data) to verify the multipart structure is correct.
内容的提问来源于stack exchange,提问作者Rahul Singh
相关产品推荐
相关产品推荐

