2014-02-18 2 views
3

Я пытаюсь использовать sonicAPI file/upload API в C#.Эквивалент параметра «curl -F» для System.Net.Http.MultipartFormDataContent?

Моя попытка перевести локон пример C# с HttpClient и MultipartFormDataContent возвращает ошибку 400/Bad Request.

Содержание ответа:

<?xml version="1.0" encoding="UTF-8"?> 
<response> 
    <status code="400" /> 
    <errors> 
     <error message="File upload failed: file is missing." parameter="file" error_code="10" /> 
    </errors> 
</response> 

Пример локонов командной строки приведены в документации:

curl https://api.sonicapi.com/file/upload?access_id=$ACCESS_ID [email protected]

код я созданного до сих пор:

public async Task<HttpResponseMessage> Post(string id, string fileName) 
{ 
    string url = string.Format("http://api.sonicapi.com/file/upload?access_id={0}", id); 
    var stream = new FileStream(fileName, FileMode.Open); 

    var client = new HttpClient { Timeout = TimeSpan.FromMinutes(10) }; 
    var content = new MultipartFormDataContent(); 
    content.Add(new StreamContent(stream), "file"); 

    HttpResponseMessage message = await client.PostAsync(url, content); 
    string s = await message.Content.ReadAsStringAsync(); 

    return message; 
} 

Я пытался удалить "file" из content.Add(new StreamContent(stream), "file"); но это не помогло.

Примечание: загрузка происходит (т.е. она не возвращается сразу)

Вы знаете, что является эквивалентом локонов параметра -F при использовании веб-классов .NET?

РЕДАКТИРОВАТЬ:

Выход завитка -v

* Hostname was NOT found in DNS cache 
* Trying 87.106.252.119... 
* Connected to api.sonicapi.com (87.106.252.119) port 80 (#0) 
> POST /file/upload?access_id=xxxxxxxxxxxx HTTP/1.1 
> User-Agent: curl/7.35.0 
> Host: api.sonicapi.com 
> Accept: */* 
> Content-Length: 882266 
> Expect: 100-continue 
> Content-Type: multipart/form-data; boundary=------------------------b3c6dc0fc9 
34fc71 
> 
< HTTP/1.1 100 Continue 
< HTTP/1.1 201 Created 
* Server nginx/0.7.67 is not blacklisted 
< Server: nginx/0.7.67 
< Date: Tue, 18 Feb 2014 21:14:09 GMT 
< Content-Type: application/xml 
< Connection: keep-alive 
< X-Powered-By: Express 
< X-Sonicapi-Request-Id: 6422cd9a-6069-4c2f-a3c5-0865c8ada6d5 
< Access-Control-Allow-Origin: * 
< location: /file/download?file_id=dae4e051-fe11-4058-a009-855dbb74de50 
< X-Sonicapi-File-Id: dae4e051-fe11-4058-a009-855dbb74de50 
< Content-Length: 249 
< 
<?xml version="1.0" encoding="utf-8"?><response><status code="201"/><file file_i 
d="dae4e051-fe11-4058-a009-855dbb74de50" status="ready" href="/file/download?fil 
e_id=dae4e051-fe11-4058-a009-855dbb74de50" remaining_lifetime_seconds="3599"/></ 
response>* Connection #0 to host api.sonicapi.com left intact 

Вывод запроса с помощью неудобный:

POST http://api.sonicapi.com/file/upload?access_id=xxxxxxxx 
HTTP/1.1 
Content-Type: multipart/form-data; boundary="bd6fba7f-c173-4470-9c44-c9cc91f618a9" 
Host: api.sonicapi.com 
Content-Length: 882175 
Expect: 100-continue 
Connection: Keep-Alive 

--bd6fba7f-c173-4470-9c44-c9cc91f618a9 
Content-Disposition: form-data; name=file 

RIFFvu 
�WAVEfmt 

(усеченного)

+1

Если посмотреть на (и/или показать нам) запрос HTTP, порожденного завитка (с помощью Fiddler, например), и сравнить его с запросом HTTP, генерируемого кода, это может дать некоторое представление. – bzlm

+0

Я добавил оба выхода, к сожалению, я не могу получить результат работы curl в cmd с Fiddly, ничего не перехватывается. – Aybe

+1

Вы должны [вручную сказать curl использовать прокси-сервер (т. Е. «Fiddly»)] (http://curl.haxx.se/mail/archive-2007-03/0032.html). Кроме того, какой второй запрос HTTP? Он просто говорит «запрос» в вашем вопросе, и он выглядит радикально отличным от вашего другого HTTP-запроса (который говорит «curl -v»). Кроме того, ваш 'curl -v' фактически' curl -v -F ... '? – bzlm

ответ

7

Благодаря @bzlm, используя Fiddler Мне удалось отследить, чего не хватает:

  • Содержание распоряжения
  • Тип содержимого

И это необходимо установить на streamContent, а не content.

public async Task<HttpResponseMessage> Post(string id, string fileName) 
{ 
    string url = string.Format("http://api.sonicapi.com/file/upload?access_id={0}", id); 
    var stream = new FileStream(fileName, FileMode.Open); 
    string name = Path.GetFileName(fileName); 

    var client = new HttpClient { Timeout = TimeSpan.FromMinutes(10) }; 

    var streamContent = new StreamContent(stream); 
    streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data"); 
    streamContent.Headers.ContentDisposition.Name = "\"file\""; 
    streamContent.Headers.ContentDisposition.FileName = "\"" + name + "\""; 
    streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 

    var content = new MultipartFormDataContent { streamContent }; 
    HttpResponseMessage message = await client.PostAsync(url, content); 
    string s = await message.Content.ReadAsStringAsync(); 
    return message; 
} 
+0

Не забудьте отметить это как принятый ответ завтра. – bzlm

+0

Мне еще нужно подождать 1 день, прежде чем я смогу отметить это. – Aybe

+0

Пока вы ждёте, вы можете сделать Sonic C# Helper Library, чтобы другие могли легко использовать C# для использования Sonic API, без необходимости возиться, как вам нужно.У вас уже есть один вспомогательный метод. :) – bzlm

Смежные вопросы