Reputation: 87
The following code works:
string UploadWithHttpRequest(string url, string filePath, string fileName)
{
try
{
byte[] fileByteArray = File.ReadAllBytes(filePath);
string formDataBoundary = $"----------{Guid.NewGuid():N}";
string contentType = "multipart/form-data; boundary=" + formDataBoundary;
byte[] formData = GetMultipartFormDataForUpload(fileByteArray, fileName, contentType, formDataBoundary);
var request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "POST";
request.ContentType = contentType;
request.UserAgent = Credentials.UserName;
request.CookieContainer = new CookieContainer();
request.ContentLength = formData.Length;
request.Credentials = Credentials;
using (Stream RequestStream = request.GetRequestStream())
{
RequestStream.Write(formData, 0, formData.Length);
RequestStream.Close();
}
var response = request.GetResponse() as HttpWebResponse;
var ResponseReader = new StreamReader(response.GetResponseStream());
string FullResponse = ResponseReader.ReadToEnd();
response.Close();
return FullResponse;
}
catch (Exception ex)
{
throw ex;
}
}
byte[] GetMultipartFormDataForUpload(byte[] byteArray, string fileName, string contentType, string Boundary)
{
Stream FormDataStream = new MemoryStream();
string Header = string.Format("--{0}" + Environment.NewLine + "Content-Disposition: form-data; name=\"{1}\"; filename=\"{2}\""
+ Environment.NewLine + Environment.NewLine, Boundary, "file", fileName);
FormDataStream.Write(Encoding.UTF8.GetBytes(Header), 0, Encoding.UTF8.GetByteCount(Header));
FormDataStream.Write(byteArray, 0, byteArray.Length);
string Footer = Environment.NewLine + "--" + Boundary + "--" + Environment.NewLine;
FormDataStream.Write(Encoding.UTF8.GetBytes(Footer), 0, Encoding.UTF8.GetByteCount(Footer));
FormDataStream.Position = 0L;
var FormData = new byte[(int)(FormDataStream.Length - 1L + 1)];
FormDataStream.Read(FormData, 0, FormData.Length);
FormDataStream.Close();
return FormData;
}
But instead of using HttpRequest I'd like to use HttpClient and instead of doing all the encoding manually (especially in GetMultipartFormDataForUpload) I'd like to use the class MultipartFormDataContent. When I try this, I always get a 500 from the server. This is what I have tried so far:
async Task<string> UploadWithHttpClient(string url, string filePath, string fileName)
{
try
{
byte[] fileByteArray = File.ReadAllBytes(filePath);
var content = new MultipartFormDataContent("------------" + Guid.NewGuid());
var byteArrayContent = new ByteArrayContent(fileByteArray, 0, fileByteArray.Length);
//Option 1
byteArrayContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "file",
FileName = fileName
};
//Option 2
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "file",
FileName = fileName
};
content.Add(byteArrayContent, "file");
var client = new HttpClient();
var response = await client.PostAsync(url, content);
var result = await response.Content.ReadAsStringAsync();
return result;
}
catch (Exception ex)
{
throw ex;
}
}
What is the right way to replace the httprequest with the httpclient? Where does the content-disposition header belong (is one of the options I have tried correct)? If yes what else is my problem?
Upvotes: 2
Views: 10430
Reputation: 87
the following code worked for me in the end:
async Task<string> UploadWithHttpClient(string url, string filePath, string fileName)
{
try
{
byte[] fileByteArray = File.ReadAllBytes(filePath);
var content = new MultipartFormDataContent("------------" + Guid.NewGuid());
var byteArrayContent = new ByteArrayContent(fileByteArray);
byteArrayContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/pdf");
content.Add(byteArrayContent, "\"file\"", $"\"{fileName}\"");
var client = new HttpClient();
var response = await client.PostAsync(url, content);
var result = await response.Content.ReadAsStringAsync();
return result;
}
catch (Exception ex)
{
throw ex;
}
}
```
Upvotes: 2