Reputation: 759
Server-side:
public HttpResponseMessage Post([FromUri]string machineName)
{
HttpResponseMessage result = null;
var httpRequest = HttpContext.Current.Request;
if (httpRequest.Files.Count > 0 && !String.IsNullOrEmpty(machineName))
...
Client-side:
public static void PostFile(string url, string filePath)
{
if (String.IsNullOrWhiteSpace(url) || String.IsNullOrWhiteSpace(filePath))
throw new ArgumentNullException();
if (!File.Exists(filePath))
throw new FileNotFoundException();
using (var handler = new HttpClientHandler { Credentials= new NetworkCredential(AppData.UserName, AppData.Password, AppCore.Domain) })
using (var client = new HttpClient(handler))
using (var content = new MultipartFormDataContent())
using (var ms = new MemoryStream(File.ReadAllBytes(filePath)))
{
var fileContent = new StreamContent(ms);
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = Path.GetFileName(filePath)
};
content.Add(fileContent);
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
var result = client.PostAsync(url, content).Result;
result.EnsureSuccessStatusCode();
}
}
At the server-side httpRequest.Files collection is always empty. But headers (content-length etc...) are right.
Upvotes: 12
Views: 21867
Reputation: 25907
Everything looks good in your code except the content type which should be multipart/form-data
. Please try changing your code to reflect the correct content type:
content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data");
You might want to refer to this post as to why setting the content type to application/octet-stream
doesn't make sense from client side.
Upvotes: 1
Reputation: 18922
In case someone else has the same problem: make sure your boundary string is valid, e.g. don't do this:
using (var content =
new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture)))
{
...
}
This failed for me due to an invalid boundary character, maybe the "/" date separator. At least this solved my problem when accessing Context.Request.Files
in a Nancy
controller (which was always empty).
Better to use something like DateTime.Now.Ticks.ToString("x")
instead.
Upvotes: 0
Reputation: 3959
You shouldn't use HttpContext for getting the files in ASP.NET Web API. Take a look at this example written by Microsoft (http://code.msdn.microsoft.com/ASPNET-Web-API-File-Upload-a8c0fb0d/sourcecode?fileId=67087&pathId=565875642).
public class UploadController : ApiController
{
public async Task<HttpResponseMessage> PostFile()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
try
{
StringBuilder sb = new StringBuilder(); // Holds the response body
// Read the form data and return an async task.
await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the form data.
foreach (var key in provider.FormData.AllKeys)
{
foreach (var val in provider.FormData.GetValues(key))
{
sb.Append(string.Format("{0}: {1}\n", key, val));
}
}
// This illustrates how to get the file names for uploaded files.
foreach (var file in provider.FileData)
{
FileInfo fileInfo = new FileInfo(file.LocalFileName);
sb.Append(string.Format("Uploaded file: {0} ({1} bytes)\n", fileInfo.Name, fileInfo.Length));
}
return new HttpResponseMessage()
{
Content = new StringContent(sb.ToString())
};
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
}
Upvotes: 12
Reputation: 2803
Try this method :
public void UploadFilesToRemoteUrl()
{
string[] files = { @"your file path" };
string url = "Your url";
long length = 0;
string boundary = "----------------------------" +
DateTime.Now.Ticks.ToString("x");
HttpWebRequest httpWebRequest2 = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest2.ContentType = "multipart/form-data; boundary=" +
boundary;
httpWebRequest2.Method = "POST";
httpWebRequest2.KeepAlive = true;
httpWebRequest2.Credentials =
System.Net.CredentialCache.DefaultCredentials;
Stream memStream = new System.IO.MemoryStream();
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" +
boundary + "\r\n");
string formdataTemplate = "\r\n--" + boundary +
"\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
memStream.Write(boundarybytes, 0, boundarybytes.Length);
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n Content-Type: application/octet-stream\r\n\r\n";
for (int i = 0; i < files.Length; i++)
{
//string header = string.Format(headerTemplate, "file" + i, files[i]);
string header = string.Format(headerTemplate, "uplTheFile", files[i]);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
FileStream fileStream = new FileStream(files[i], FileMode.Open,
FileAccess.Read);
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
memStream.Write(buffer, 0, bytesRead);
}
memStream.Write(boundarybytes, 0, boundarybytes.Length);
fileStream.Close();
}
httpWebRequest2.ContentLength = memStream.Length;
Stream requestStream = httpWebRequest2.GetRequestStream();
memStream.Position = 0;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
requestStream.Close();
WebResponse webResponse2 = httpWebRequest2.GetResponse();
Stream stream2 = webResponse2.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
webResponse2.Close();
httpWebRequest2 = null;
webResponse2 = null;
}
Upvotes: 0