1
votes

I Tries to upload a file using the HTTPWebrequest(multipart/form-data).

So I see a few pages, and wrote the following code :

var boundary = "----------" + DateTime.Now.Ticks.ToString("x");
byte[] boundaryBytes = Encoding.ASCII.GetBytes(boundary);

var template = boundary + "\r\n" +
               "Content-Disposition: form-data; name=\"{0}\"" + "\r\n\r\n" +
               "{1}\r\n";

// Request Header
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://domain.com/test.php");
req.Method = "POST";
req.KeepAlive = true;
req.ContentType = "multipart/form-data; boundary=" + boundary;
req.CookieContainer = COOKIE;


Stream ms = new MemoryStream();

string formItem;
byte[] formItemBytes;

string fileName = Path.GetFileName(@"C:\Users\Username\Image.jpg");

// POST Data
formItem = string.Format(template, "Filename", fileName);
formItemBytes = Encoding.UTF8.GetBytes(formItem);
ms.Write(formItemBytes, 0, formItemBytes.Length);

formItem = string.Format(template, "Username", "RedPetals");
formItemBytes = Encoding.UTF8.GetBytes(formItem);
ms.Write(formItemBytes, 0, formItemBytes.Length);

var headerTemplate = "\r\nContent-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n";
string header = string.Format(headerTemplate, "Image", fileName);
byte[] headerBytes = Encoding.UTF8.GetBytes(header);

ms.Write(boundaryBytes, 0, boundaryBytes.Length);
ms.Write(headerBytes, 0, headerBytes.Length);

using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
    byte[] buffer = new byte[1024];

    int bytesRead = 0;
    while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) != 0)
    {
        ms.Write(buffer, 0, bytesRead);
    }
}

byte[] boundaryEndBytes = Encoding.ASCII.GetBytes(boundary + "--");
ms.Write(boundaryEndBytes, 0, boundaryEndBytes.Length);

req.ContentLength = ms.Length;

ms.Position = 0;
byte[] tempBuffer = new byte[ms.Length];
ms.Read(tempBuffer, 0, tempBuffer.Length);
ms.Close();

using(Stream rs = req.GetRequestStream())
{
    rs.Write(tempBuffer, 0, tempBuffer.Length);
}

HttpWebResponse response = (HttpWebResponse)req.GetResponse();
string result = "";

if (response.StatusCode == HttpStatusCode.OK)
{
    Stream resStream = response.GetResponseStream();
    StreamReader readStream = new StreamReader(resStream, Encoding.UTF8);
    result = readStream.ReadToEnd();

    Console.Write(result);

    resStream.Close();
    readStream.Close();
}

But does not pass POST data.. Is there a part I missed?

HttpAnalyzer Post 'Data'(Formdata tab is 'No data to display') :

----------8d1984e7dd49750

Content-Disposition: form-data; name="Filename"

Image.jpg

----------8d1984e7dd49750

Content-Disposition: form-data; name="Username"

RedPetals

----------8d1984e7dd49750

Content-Disposition: form-data; name="img"; filename="Image.jpg"

Content-Type: application/octet-stream

???

----------8d1984e7dd49750--

Response result :

// echo var_dump($_POST); echo var_dump($_FILES);

array(0) { } array(0) { }


Resolved

//var boundary = "----------" + DateTime.Now.Ticks.ToString("x");
var boundary = "--------" + DateTime.Now.Ticks.ToString("x");

// var template = boundary + "\r\n" +
//                "Content-Disposition: form-data; name=\"{0}\"" + "\r\n\r\n" +
//                "{1}\r\n";
var template = "--" + boundary + "\r\n" +
               "Content-Disposition: form-data; name=\"{0}\"" + "\r\n\r\n" +
               "{1}\r\n";
1
I would use HttpClient+MultipartFormDataContent instead of forming the headers manually.L.B

1 Answers

0
votes

Here's my solution when I encountered this issue:

Client:

 public async Task UploadImage(byte[] image, string url)
        {
            Stream stream = new System.IO.MemoryStream(image);
            HttpStreamContent streamContent = new HttpStreamContent(stream.AsInputStream());

            Uri resourceAddress = null;
            Uri.TryCreate(url.Trim(), UriKind.Absolute, out resourceAddress);
            Windows.Web.Http.HttpRequestMessage request = new Windows.Web.Http.HttpRequestMessage(Windows.Web.Http.HttpMethod.Post, resourceAddress);
            request.Content = streamContent;

            var httpClient = new Windows.Web.Http.HttpClient();
            var cts = new CancellationTokenSource();
            Windows.Web.Http.HttpResponseMessage response = await httpClient.SendRequestAsync(request).AsTask(cts.Token);
        }

Controller:

public async Task<HttpResponseMessage> Post()
{
    Stream requestStream = await this.Request.Content.ReadAsStreamAsync();
    byte[] byteArray = null;
    using (MemoryStream ms = new MemoryStream())
    {
        await requestStream.CopyToAsync(ms);
        byteArray = ms.ToArray();
    }
    .
    .
    .
    return Request.CreateResponse(HttpStatusCode.OK);
}