3

I am trying to upload a multi-part form with HTTPWebRequest & all is ok until I added an image to upload, mainly I am trying to do exactly the same request as a browser makes which looks like this:

-----------------------------41184676334
Content-Disposition: form-data; name="file"; filename="guitar tape.jpg"
Content-Type: image/jpeg

IMAGEDATAHERE
-----------------------------41184676334
Content-Disposition: form-data; name="save"

save
-----------------------------41184676334--

I am lost on how to format / read the image to set it into the request that I am making below:

            Dim boundary As String = "-----------------------------" & DateTime.Now.Ticks.ToString("x")
        Dim req As HttpWebRequest = DirectCast(WebRequest.Create("http://www.mysite.com/upload.php"), HttpWebRequest)
        req.Method = "POST"
        req.ContentType = "multipart/form-data; boundary=" & "---------------------------" & DateTime.Now.Ticks.ToString("x")
        req.KeepAlive = False
        Dim builder As New StringBuilder()
        builder.Append(boundary & vbCrLf & "Content-Disposition: form-data; name=""variable1""" & vbCrLf & vbCrLf & "1" & vbCrLf)
        builder.Append(boundary & vbCrLf & "Content-Disposition: form-data; name=""file""; filename=""" & FileName & """" & vbCrLf)
        builder.Append("Content-Type: application/octet-stream")
        builder.Append(vbCrLf & vbCrLf)
        ' Add Photo Here
        If UpdateImage = True Then
            ' Load Image
            Dim ImageData As System.Drawing.Image
            Dim fs As New System.IO.FileStream(ImagePath, System.IO.FileMode.Open)
            ImageData = Image.FromStream(fs)
            fs.Close()
            ' Add Image To Header
            builder.Append(ImageData)
            builder.Append(vbCrLf)
        Else
            builder.Append(vbCrLf)
        End If
        builder.Append(boundary & vbCrLf & "Content-Disposition: form-data; name=""save""" & vbCrLf & vbCrLf & "save")
        ' Footer Bytes
        Dim close As Byte() = Encoding.UTF8.GetBytes("--")
        Dim postHeader As String = builder.ToString()
        Dim postHeaderBytes As Byte() = Encoding.UTF8.GetBytes(postHeader)
        Dim boundaryBytes As Byte() = Encoding.ASCII.GetBytes(vbCrLf & boundary & "--" & vbCrLf)
        Dim length As Long = postHeaderBytes.Length + boundaryBytes.Length
        req.ContentLength = length
        Dim requestStream As Stream = req.GetRequestStream()
        Dim fulllength As Integer = postHeaderBytes.Length + boundaryBytes.Length
        ' Write out our post header
        requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length)
        ' Write out the trailing boundary
        requestStream.Write(boundaryBytes, 0, boundaryBytes.Length)
        Dim responce As WebResponse
        responce = req.GetResponse()
        requestStream.Close()
        Dim s As Stream = responce.GetResponseStream()
        Dim sr As New StreamReader(s)
        Dim Content As String = sr.ReadToEnd()

At the moment it is simply posting "System.Drawing.Bitmap" as the image data but I am not sure how to get the same raw data for the image that looks like this:

    J©õݨe‚Lnž¿Ëã/ǧúÐ5ý¼C÷Cý>ß’t;fm—=Äw:�/E±ËÙÏ$á@%Pc>×    Šgw.²Ab“:ÅÓù:ϯÌh6à€Z§Ó‚g£®hÚD6¨Ø^Ú2ô`ä¨L�YÆÄÅCX#I“ÈÌãj¦L˜•’|¥�Eb¡ëQ–¤Ú, 3\UzL  öÔoj4�•±’u«c¼#„oÕ`îF>·o—ŠûÅ«ÎÑ™¶Ç˜ýº*i°œÈVŒ�Qû”Ñ[.�ÔmçE•ì¦eNCh�Ù
é§�É$m¿ôš"»ÌNæ(VÌmp›F¹XÈ88™ªüµ…d•XµÔÜ#�ˆŠv‘º‚F‚§Yûb

Any ideas on how I could do this or would I need to change my methods?

Chris
  • 73
  • 1
  • 2
  • 7

2 Answers2

1
    builder.Append(ImageData)

is not correct. you need read the image as byte, then add the byte[] to the multipart post.

see details at Using HttpWebRequest to POST data/upload image using multipart/form-data

and make sure use a http sniffer (i.e. fiddler) to see what it is actually sending.

first, load image into byte array, then convert it to base64:

imgBase64 = Convert.ToBase64String(my_image_byte_array)
Community
  • 1
  • 1
urlreader
  • 6,319
  • 7
  • 57
  • 91
  • Thanks for the reply, I tried this before & it posts content like: /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAICAgICAQICAgIDAgIDAwYEAwMDAwcFBQQGCAc (base64) What I was looking to do is post the actual image data like in the example data. – Chris Dec 17 '12 at 17:08
  • if you see base64 format in the fiddler, then you HAVE TO post it as base64 format. It is the image, just in a different format. On the server, it will decode the base64 format to save the image. If you post the raw data, it will fail. – urlreader Dec 17 '12 at 17:13
  • At the moment the server response is invalid image although the data being posted is 100% ok apart from the actual image data is in a different format. – Chris Dec 17 '12 at 17:23
  • yes, the response is very clear. you post the wrong data. the raw data is not base64 based, so the server accept data, but can not convert it to valid image. that's why responsed 'invalid image'. See above for convert to base64. – urlreader Dec 17 '12 at 17:31
  • I changed the code to: Dim ImageData() As Byte = File.ReadAllBytes(ImagePath) Dim NewImageData As String = Convert.ToBase64String(ImageData) After this the data looks like: /9j/4AAQSkZJR whereas Fiddler shows a normal upload as: J©õݨe‚Lnž¿Ëã/ǧúÐ5ý¼C & with this change the server responds Invalid Image Type. – Chris Dec 17 '12 at 17:44
0

My "OpenFileDialog" name is "file". When a "button" is clicked it will show a pop up dialog for selecting jpg, jpeg, png image files, it can also add bmp or any image file type. Then after the selection of a image file it will show on "PictureBox" i name it as "picboxProfileID".

In Visual Basic:

  file.Filter = "image file (*.jpg, *.jpeg, *.png) | *.jpg; *.jpeg; *.png | all files (*.*) | *.*"
    If (file.ShowDialog <> Windows.Forms.DialogResult.Cancel) Then
        picboxProfileID.Image = Image.FromFile(file.FileName)
        picboxProfileID.ImageLocation = file.FileName
        txtName.Text = file.FileName
        My.Computer.Network.UploadFile(file.FileName, "http://localhost/VTVTS/uploadImageSample.php")
    Else
        picboxProfileID.Image = Nothing
    End If

The destination of the file uploaded will be uploaded on the "images/" of the parent folder php file created.

In PHP:

<?php
$response = array();
$image = $_FILES['file'];

$imageName = $image['name'];
$imageTmpName = $image['tmp_name'];
$imageSize = $image['size'];
$imageError = $image['error'];
$imageType = $image['type'];

$fileExt = explode('.', $imageName);
$fileActualExt = strtolower(end($fileExt));

$allowed = array('jpg', 'jpeg', 'png');
if(in_array($fileActualExt, $allowed)){
    $fileNameNew = uniqid('', true).".".$fileActualExt;
    $fileDestination = 'images/'.$fileNameNew;
    $newDestination = move_uploaded_file($imageTmpName, $fileDestination);
    $response['error'] = false;
    $response['message'] = "Upload Image Successful";
}else{
    $response['error'] = true;
    $response['message'] = "You cannot upload files of this type!";
}
echo json_encode($response);

Happy Coding!

Sauer Voussoir
  • 111
  • 2
  • 12