问题
I'm trying to upload an image from Xamarin to php using WebClient.
I've tried this code:
Xamarin:
System.Net.WebClient client = new System.Net.WebClient();
Uri uri = new Uri($"{APIConfig.SourceUri}/post/postProfilePicBETA");
client.Headers.Add("user-agent", GetString(Resource.String.appVersion));
client.UploadFileAsync(uri, resultUri.Path);
client.UploadFileCompleted += delegate { loadingLayout.Visibility = ViewStates.Gone; this.Finish(); };
PHP Code:
if(!isset($_FILES['image']))
{
echo json_encode(array("state" => "empty"));
}
else
{
$imageid = $this->getRandom(20);
move_uploaded_file($_FILES['image']['tmp_name'], "users/".$imageid.".jpg");
}
But there is no image on the server.
I've tried using a form in html and it worked.
回答1:
The main problem is that you are not sending any information to the webservice about the field name.
In short: PHP and .NET simply need to match with the field name. Sadly with WebClient it is hardcoded to "file".
[file] => Array
(
[name] => testabc.jpg
[type] => application/octet-stream
[tmp_name] => /tmp/phpgMGIJp
[error] => 0
[size] => 31211
)
What you could do is to simply change the "image" key to "file" in your PHP code, but that would be too generic in my opinion and possibly break any other clients using the same upload webservice. Therefore it is better to actually send the field name.
For example to modify your PHP file to:
$keyExpected = 'image';
if(isset($_FILES['file']) && !isset($_FILES[$keyExpected])) {
//dotnet detected...
$keyExpected = 'file';
}
if(!isset($_FILES[$keyExpected]))
{
echo json_encode(array("state" => "empty"));
}
else
{
$imageid = $this->getRandom(20);
move_uploaded_file($_FILES[$keyExpected]['tmp_name'], "users/".$imageid.".jpg");
}
Yet you do not want to edit the PHP-side and only the .NET part then you should go with a proper HTTP Client.
Even for the one from System.Net.Http
(remember to import System.Net.Http assembly!):
var content = new MultipartFormDataContent();
string fileName = "file.jpg";
string fieldName = "image";
content.Add(new StreamContent(new FileStream(@"\path\to\your\file.jpg", FileMode.Open, FileAccess.Read, FileShare.Read)), fieldName, fileName);
//content.Add( new StreamContent(mediaFile.GetStream()), "file", mediaFile.Path);
var httpClient = new HttpClient();
var uploadServiceBaseAddress = "http://host.pl/your_web_service.php"
var httpResponseMessage = await httpClient.PostAsync(uploadServiceBaseAddress, content);
//if you output any results...
string result = await httpResponseMessage.Content.ReadAsStringAsync();
if you are using the MediaFile plugin it can be as follows:
var content = new MultipartFormDataContent();
string fileName = Path.GetFileName(mediaFile.path);
string fieldName = "image";
content.Add(new StreamContent(mediaFile.GetStream(), FileMode.Open, FileAccess.Read, FileShare.Read)), fieldName, fileName);
var httpClient = new HttpClient();
var uploadServiceBaseAddress = "http://host.pl/your_web_service.php"
var httpResponseMessage = await httpClient.PostAsync(uploadServiceBaseAddress, content);
//if you output any results...
string result = await httpResponseMessage.Content.ReadAsStringAsync();
来源:https://stackoverflow.com/questions/59594235/image-is-not-being-upload-on-php-from-xamarin