Каков самый простой способ отправить запрос HTTP POST с типом контента multipart/form-data из С#? Должен быть лучший способ, чем создать собственный запрос.
Причина, по которой я спрашиваю, - загрузить фотографии в Flickr, используя этот api:
Каков самый простой способ отправить запрос HTTP POST с типом контента multipart/form-data из С#? Должен быть лучший способ, чем создать собственный запрос.
Причина, по которой я спрашиваю, - загрузить фотографии в Flickr, используя этот api:
Прежде всего, нет ничего плохого в чистой ручной реализации HTTP-команд с использованием .Net framework. Имейте в виду, что это фреймворк, и он должен быть довольно общим.
Во-вторых, я думаю, вы можете попробовать выполнить реализацию браузера в .NET. Я видел этот, возможно, он охватывает вопрос, о котором вы просили. Или вы можете просто найти " С# http put get post request". Один из результатов приводит к несвободной библиотеке, которая может быть полезна (Chilkat Http)
Если вам удастся написать собственную инфраструктуру HTTP-команд поверх .Net - я думаю, что мы все можем наслаждаться, если вы разделите ее: -)
Если вы используете .NET 4.5, используйте это:
public string Upload(string url, NameValueCollection requestParameters, MemoryStream file)
{
var client = new HttpClient();
var content = new MultipartFormDataContent();
content.Add(new StreamContent(file));
System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<string, string>> b = new List<KeyValuePair<string, string>>();
b.Add(requestParameters);
var addMe = new FormUrlEncodedContent(b);
content.Add(addMe);
var result = client.PostAsync(url, content);
return result.Result.ToString();
}
В противном случае На основании ответа Райана я загрузил библиотеку и немного изменил ее.
public class MimePart
{
NameValueCollection _headers = new NameValueCollection();
byte[] _header;
public NameValueCollection Headers
{
get { return _headers; }
}
public byte[] Header
{
get { return _header; }
}
public long GenerateHeaderFooterData(string boundary)
{
StringBuilder sb = new StringBuilder();
sb.Append("--");
sb.Append(boundary);
sb.AppendLine();
foreach (string key in _headers.AllKeys)
{
sb.Append(key);
sb.Append(": ");
sb.AppendLine(_headers[key]);
}
sb.AppendLine();
_header = Encoding.UTF8.GetBytes(sb.ToString());
return _header.Length + Data.Length + 2;
}
public Stream Data { get; set; }
}
public string Upload(string url, NameValueCollection requestParameters, params MemoryStream[] files)
{
using (WebClient req = new WebClient())
{
List<MimePart> mimeParts = new List<MimePart>();
try
{
foreach (string key in requestParameters.AllKeys)
{
MimePart part = new MimePart();
part.Headers["Content-Disposition"] = "form-data; name=\"" + key + "\"";
part.Data = new MemoryStream(Encoding.UTF8.GetBytes(requestParameters[key]));
mimeParts.Add(part);
}
int nameIndex = 0;
foreach (MemoryStream file in files)
{
MimePart part = new MimePart();
string fieldName = "file" + nameIndex++;
part.Headers["Content-Disposition"] = "form-data; name=\"" + fieldName + "\"; filename=\"" + fieldName + "\"";
part.Headers["Content-Type"] = "application/octet-stream";
part.Data = file;
mimeParts.Add(part);
}
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
req.Headers.Add(HttpRequestHeader.ContentType, "multipart/form-data; boundary=" + boundary);
long contentLength = 0;
byte[] _footer = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");
foreach (MimePart part in mimeParts)
{
contentLength += part.GenerateHeaderFooterData(boundary);
}
//req.ContentLength = contentLength + _footer.Length;
byte[] buffer = new byte[8192];
byte[] afterFile = Encoding.UTF8.GetBytes("\r\n");
int read;
using (MemoryStream s = new MemoryStream())
{
foreach (MimePart part in mimeParts)
{
s.Write(part.Header, 0, part.Header.Length);
while ((read = part.Data.Read(buffer, 0, buffer.Length)) > 0)
s.Write(buffer, 0, read);
part.Data.Dispose();
s.Write(afterFile, 0, afterFile.Length);
}
s.Write(_footer, 0, _footer.Length);
byte[] responseBytes = req.UploadData(url, s.ToArray());
string responseString = Encoding.UTF8.GetString(responseBytes);
return responseString;
}
}
catch
{
foreach (MimePart part in mimeParts)
if (part.Data != null)
part.Data.Dispose();
throw;
}
}
}
У меня был успех с кодом, опубликованным в aspnetupload.com. В результате я создал свою собственную версию библиотеки UploadHelper, которая совместима с Compact Framework. Хорошо работает, кажется, делает именно то, что вам нужно.
Я не пробовал это сам, но, похоже, для С# существует встроенный способ (хотя и не очень известный, по-видимому...):
private static HttpClient _client = null;
private static void UploadDocument()
{
// Add test file
var httpContent = new MultipartFormDataContent();
var fileContent = new ByteArrayContent(File.ReadAllBytes(@"File.jpg"));
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "File.jpg"
};
httpContent.Add(fileContent);
string requestEndpoint = "api/Post";
var response = _client.PostAsync(requestEndpoint, httpContent).Result;
if (response.IsSuccessStatusCode)
{
// ...
}
else
{
// Check response.StatusCode, response.ReasonPhrase
}
}
Попробуйте и дайте мне знать, как это происходит.
Ура!
Класс System.Net.WebClient может быть тем, что вы ищете. Проверьте документацию для WebClient.UploadFile, она должна позволить вам загрузить файл на указанный ресурс через одну из перегрузок UploadFile. Я думаю, что это метод, который вы хотите использовать для публикации данных...
Он может быть использован как.... обратите внимание, что это просто не проверенный код кода...
WebClient webClient = новый WebClient();
webClient.UploadFile( " http://www.url.com/ReceiveUploadedFile.aspx", "POST", @ "c:\myfile.txt" );
Вот ссылка MSDN, если вы заинтересованы.
http://msdn.microsoft.com/en-us/library/system.net.webclient.uploadfile.aspx
Надеюсь, что это поможет.
Я обычно считаю Fiddler лучшим инструментом для этой работы. Очень легко создавать запросы, и даже создает для вас некоторые заголовки.