Xamarin.forms 使用 php 将图像上传到服务器目录

Posted

技术标签:

【中文标题】Xamarin.forms 使用 php 将图像上传到服务器目录【英文标题】:Xamarin.forms upload image to server directory using php 【发布时间】:2019-02-02 14:04:34 【问题描述】:

现在我正在 Visual Studio 2017 中的 Xamarin.Forms 上做项目。 我正在尝试使用 HttpClient 上传图像并通过 php 代码将文件发布到我的服务器目录。但是下面的代码仍然无法正常工作。

我可以在我的应用程序上获取照片并显示,但无法上传到服务器!

请帮忙!

C# 文件

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 代码

<?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>';
?>

【问题讨论】:

html 包含您上传的二进制数据中的无效字符。您需要使用 Convert.ToBase64String(string) 将二进制文件转换为 64 位字符串 这里有一个关于这个的讨论。你可以参考。forums.xamarin.com/discussion/97078/… 【参考方案1】:

这就是我使用 Xamarin Forms 和 PHP 的方式。在我的网站上查看代码 here.

C#代码是

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;



而PHP代码是

//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().'"';

【讨论】:

以上是关于Xamarin.forms 使用 php 将图像上传到服务器目录的主要内容,如果未能解决你的问题,请参考以下文章

如何调整 xamarin.forms 中的图像大小?

图像不显示 Xamarin.Forms

Xamarin Forms Android 项目图像未显示但在 iOS 上正确显示

Xamarin.Forms 警告:尝试使用 iOS 图像/手势识别器在其视图不在窗口层次结构中的 * 上呈现 *

Xamarin.Forms:将 ImageSource 转换为 Image Byte 数组

使用PCL Xamarin Forms将图像上载到FTP服务器