使用RestSharp调用Freshdesk outbound_email接口带附件报错求助
调用Freshdesk的outbound_email接口发送带附件邮件时,不带附件的请求可正常执行并收到邮件,但添加附件后返回Bad Request,所有字段被标记为无效。该功能在Postman中可正常运行,更换为HttpClient后仍出现相同错误。
原代码
var client = new RestClient(outboundEmail); var request = new RestRequest("", Method.Post); request.AddHeader("Authorization", "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(apiKey + ":X"))); request.AddHeader("Accept", "application/json"); request.AddHeader("Content-Type", "multipart/form-data"); request.AddFile("attachments[]", "filePath"); request.AddParameter("email", myEmail); request.AddParameter("subject", subject); request.AddParameter("description", description); request.AddParameter("status", status); request.AddParameter("priority", priority); request.AddParameter("email_config_id", emailConfigID); var response = client.Execute(request);
返回错误信息
"description":"Validation failed","errors":
[{"field":"email\n","message":"Unexpected/invalid field in request","code":"invalid_field"},
{"field":"subject\n","message":"Unexpected/invalid field in request","code":"invalid_field"},{"field":"description\n","message":"Unexpected/invalid field in request","code":"invalid_field"},{"field":"status\n","message":"Unexpected/invalid field in request","code":"invalid_field"},{"field":"priority\n","message":"Unexpected/invalid field in request","code":"invalid_field"},{"field":"email_config_id\n","message":"Unexpected/invalid field in request","code":"invalid_field"}]}
问题原因
- 手动设置
Content-Type: multipart/form-data会覆盖RestSharp自动生成的包含boundary的Content-Type头,导致请求格式异常。 - 使用
AddParameter添加普通字段时,字段名被错误编码(末尾多出换行符\n),Freshdesk API无法识别这些带换行的字段名,因此返回无效字段错误。
修复方案
RestSharp修复代码
var client = new RestClient(outboundEmail); var request = new RestRequest("", Method.Post); // 保留授权和Accept头 request.AddHeader("Authorization", "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(apiKey + ":X"))); request.AddHeader("Accept", "application/json"); // 移除手动设置的Content-Type,RestSharp会自动处理multipart请求的Content-Type及boundary // request.AddHeader("Content-Type", "multipart/form-data"); // 添加附件 request.AddFile("attachments[]", "filePath"); // 使用AddStringParameter替代AddParameter,确保字段名和值正确编码 request.AddStringParameter("email", myEmail); request.AddStringParameter("subject", subject); request.AddStringParameter("description", description); request.AddStringParameter("status", status); request.AddStringParameter("priority", priority); request.AddStringParameter("email_config_id", emailConfigID); var response = client.Execute(request);
HttpClient修复代码
using (var client = new HttpClient()) { // 设置授权头 client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.Default.GetBytes(apiKey + ":X"))); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); using (var content = new MultipartFormDataContent()) { // 添加普通文本字段 content.Add(new StringContent(myEmail), "email"); content.Add(new StringContent(subject), "subject"); content.Add(new StringContent(description), "description"); content.Add(new StringContent(status), "status"); content.Add(new StringContent(priority), "priority"); content.Add(new StringContent(emailConfigID), "email_config_id"); // 添加附件,设置正确的内容类型和文件名 var fileBytes = File.ReadAllBytes("filePath"); var fileContent = new ByteArrayContent(fileBytes); fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream"); content.Add(fileContent, "attachments[]", Path.GetFileName("filePath")); var response = await client.PostAsync(outboundEmail, content); var responseString = await response.Content.ReadAsStringAsync(); } }
内容的提问来源于stack exchange,提问作者James Wilson

