0

Now i'm doing project on Xamarin.Forms in Visual Studio 2017. i'm trying to upload image using HttpClient and post file through php code to my server directory. But the code below here still not working.

I can get photo and show on my application but can not upload to server!

Please help!

C# file

async Task GetPhoto(Func<Task<MediaFile>> getPhotoFunc)
        {

            IsEnabled = false;

            try
            {
                var photo = await getPhotoFunc();
                if (photo == null)
                    return;

                Image = null;
                AllPredictions = new List<PredictionModel>();

                Image = SKBitmap.Decode(photo.GetStreamWithImageRotatedForExternalStorage());
                await PredictPhoto(photo);

                IsEnabled = true;

                byte[] bitmapData;
                var stream = new MemoryStream();
                photo.GetStream().CopyTo(stream);
                bitmapData = stream.ToArray();
                var fileContent = new ByteArrayContent(bitmapData);

                fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
                fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
                {
                    Name = "file",
                    FileName = "image_test.jpg"
                };

                string boundary = "---8393774hhy37373773";
                MultipartFormDataContent multipartContent = new MultipartFormDataContent(boundary);
                multipartContent.Add(fileContent);


                HttpClientHandler clientHandler = new HttpClientHandler();
                HttpClient httpClient = new HttpClient(clientHandler);
                HttpResponseMessage response = await httpClient.PostAsync("http://it2.sut.ac.th/project61_g23/php/upload-image.php", multipartContent);
                response.EnsureSuccessStatusCode();

            }
            catch (Exception ex)
            {
                Crashes.TrackError(ex, new Dictionary<string, string> { { "Action", "Getting predictions" } });
                await Application.Current.MainPage.DisplayAlert("Error", $"An error occured: {ex.Message}", "OK");
            }
            finally
            {
                IsEnabled = true;
            }
        }

PHP code

<?php

$uploaddir = '/Uploads/';
$uploadfile = $uploaddir.basename($_FILES['file']['name']);

echo '<pre>';
if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) {
    echo "File is valid, and was successfully uploaded.\n";
} else {
    echo "Possible file upload attack!\n";
}

echo 'Here is some more debugging info:';
print_r($_FILES);

echo '</pre>';
?>
2
  • HTML has invalid character that would be in the binary data that you are uploading. You need to convert the binary to a 64 bit string using Convert.ToBase64String(string) Commented Feb 2, 2019 at 14:20
  • Here is a discussion about this .You can refer to.forums.xamarin.com/discussion/97078/… Commented Feb 4, 2019 at 4:42

1 Answer 1

1

This is how I do it with Xamarin Forms and PHP. View the code on my website here.

C# code is

using Plugin.Media;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace UploadPicToServer
{
// Learn more about making custom code visible in the Xamarin.Forms previewer
// by visiting https://aka.ms/xamarinforms-previewer
[DesignTimeVisible(false)]
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}

private async void btnUpload_Clicked(object sender, EventArgs e)
{

if (!CrossMedia.Current.IsPickPhotoSupported)
{
await DisplayAlert("Photos Not Supported", ":( Permission not granted to photos.", "OK");
return;
}
var file = await Plugin.Media.CrossMedia.Current.PickPhotoAsync(new Plugin.Media.Abstractions.PickMediaOptions
{
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Medium,

});

if (file == null)
return;

string fileName = file.Path;
image.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});

//UploadImage1(file.AlbumPath);
UploadImage(file.GetStream(), fileName);
}
private async void UploadImage(Stream mfile, string fileName)
{
int authorID = 2;
string username = "yourusername";

var url = "https://yourwebsite.com/ba-add-profile-pic.php";
url += "?id="+ authorID +"&username="+ username; //any parameters you want to send to the php page.

try
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://yourwebsite.com/");
MultipartFormDataContent form = new MultipartFormDataContent();
//HttpContent content = new StringContent("fileToUpload");
//form.Add(content, "fileToUpload");

var stream = mfile;
StreamContent content = new StreamContent(stream);

//get file's ext
string fileExt = fileName.Substring(fileName.Length - 4);
string fName = "User-Name-Here-123" + fileExt.ToLower();

content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "fileToUpload",
FileName = fName
};
form.Add(content);
var response = await client.PostAsync(url, form);
var result = response.Content.ReadAsStringAsync().Result;

}
catch (Exception e)
{
//debug
Debug.WriteLine("Exception Caught: " + e.ToString());

return;
}
}

public static byte[] ToArray(Stream s)
{
if (s == null)
throw new ArgumentNullException(nameof(s));
if (!s.CanRead)
throw new ArgumentException("Stream cannot be read");

MemoryStream ms = s as MemoryStream;
if (ms != null)
return ms.ToArray();

long pos = s.CanSeek ? s.Position : 0L;
if (pos != 0L)
s.Seek(0, SeekOrigin.Begin);

byte[] result = new byte[s.Length];
s.Read(result, 0, result.Length);
if (s.CanSeek)
s.Seek(pos, SeekOrigin.Begin);
return result;
}
}
}

And the PHP code is

//parameters send in via querystring
if (!isset($_REQUEST['author']) || !isset($_REQUEST['username']) ) {
die('{"status" : "Bad", "reason" : "Invalid Access"}');
}

$userID = $_REQUEST['author'];
$isGood = false;
try{

$uploaddir = '../someFolderToStoreTheImage/';
$fileName = basename($_FILES['fileToUpload']['name']);
$uploadfile = $uploaddir . basename($_FILES['fileToUpload']['name']);

//CHECK IF ITS AN IMAGE OR NOT
$allowed_types = array ('image/jpeg', 'image/png', 'image/bmp', 'image/gif' );
$fileInfo = finfo_open(FILEINFO_MIME_TYPE);
$detected_type = finfo_file( $fileInfo, $_FILES['fileToUpload']['tmp_name'] );
if ( !in_array($detected_type, $allowed_types) ) {
die ( '{"status" : "Bad", "reason" : "Not a valid image"}' );
}
//

if (move_uploaded_file($_FILES['fileToUpload']['tmp_name'], $uploadfile)) {
//echo "File is valid, and was successfully uploaded.\n";
echo '{"status" : "Success", "reason" "'. $fileName .'"}';
$isGood = true;
} else {
//echo "Possible file upload attack!\n";
echo '{"status" : "Bad", "reason" : "Unable to Upload Profile Image"}';
}

}
catch(Exception $e) {
echo '{"status" : "Bad", "reason" : "'.$e->getMessage().'"}';
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.