0

我正在尝试使用 Multipart 内容类型执行批量导入,但是,无论我尝试什么,我都会不断收到错误 400 - Bad Request。不幸的是,这并没有告诉我太多,批量导入联系人的文档仅说明在验证联系人时出现错误时会发生此错误。这是我目前采用的方法:

public void SendContactFile(string contactListId, FileInfo listFile)
{
    using (var client = new HttpClient())
    {
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        using (var content = new MultipartFormDataContent())
        {
            var contentPieces = new []
            {
                new KeyValuePair<string, string>("file_name", listFile.Name),
                new KeyValuePair<string, string>("lists", contactListId), 
            };
            //var data = new StreamContent(listFile.OpenRead()); //I've tried using both StreamContent and ByteArrayContent; both returned the same failure.
            var data = new ByteArrayContent(File.ReadAllBytes(listFile.FullName));
            data.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
            {
                FileName = listFile.Name
            };//I've tried with & without this header.

            foreach (KeyValuePair<string, string> pair in contentPieces)
            {
                content.Add(new StringContent(pair.Value), pair.Key);
            }
            content.Add(data);

            var result = client.PostAsync(FullApiAddress, content).Result;
            Console.WriteLine("Status Code: {0} - {1}, Request Message: {3}", 
                result.StatusCode, 
                result.ReasonPhrase,
                result.RequestMessage);
        }
    }
}

最后,我的 Console.WriteLine() 显示的信息是:

Status Code: BadRequest - Bad Request, 
Request Message: Method: POST, 
RequestUri: 'https://api.constantcontact.com/v2/activities/addcontacts?api_key=My_API_Key',
Content: System.Net.Http.MultipartFormDataContent, 
Headers:
{
  Authorization: Bearer My-Access-Token
  Accept: application/json
  Content-Type: multipart/form-data; boundary="ead4e036-5921-4a98-847b-12h4sgre4
69c"
  Content-Length: 556
}

编辑

感谢 Amy 在下面评论中的建议,我使用 Chrome 中的 Postman 扩展程序直接从浏览器执行批量导入。通过这样做,我现在可以排除文件格式可能是我的错误的原因(并删除了这些示例),并且我也知道我正在以正确的方式处理这个问题。因此,我的代码有些地方不太对劲……有人有什么想法吗?

成功的浏览器内请求与上面显示的标头之间的一个区别是它Content-Type: mulitpart/form-data;具有边界信息,而来自浏览器的信息在每个部分都有该信息。此外,上面的代码没有显示每个部分。Postman 请求预览示例:

Content-Type: multipart/form-data
Cache-Control: no-cache

----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="file_name"

ContactList.txt
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="lists"
4

1 回答 1

1

非常感谢 Amy,在此过程中他的帮助非常宝贵!

我发现我上面使用的大多数代码都没有任何问题,除了以下几行:

data.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
    FileName = listFile.Name
};//I've tried with & without this header.

这是我在询问时正在尝试的东西,它破坏了请求。我的主要问题是 C# 在为我上传的 3 个部分编写 Content-Disposition 标头时,没有在名称值周围添加引号。这反过来又导致返回 400 - Bad Request 错误。这是工作代码现在的样子:

using (var content = new MultipartFormDataContent())
{
    var fileNameContent = new StringContent(listFile.Name);
    content.Add(fileNameContent, "\"file_name\"");

    var listContent = new StringContent(contactListId);
    content.Add(listContent, "\"lists\"");

    var dataContent = new ByteArrayContent(File.ReadAllBytes(listFile.FullName));
    content.Add(dataContent, "\"data\"");

    result = client.PostAsync(FullApiAddress, content).Result;
}

注意每个名称值周围的双引号;这个简单的更改就是我需要做的所有事情才能使请求生效。我希望这对将来的任何人都有帮助。

于 2015-03-27T20:48:16.343 回答