Upload StorageFile to a PHP File

4

I have been trying to upload a StorageFile (mostly image files) to a PHP File so that it can save into the server.

ViewModel.cs

public async Task<bool> uploadFile(StorageFile file)
{
    try
    {
        using (HttpMultipartFormDataContent form = new HttpMultipartFormDataContent())
            {
                using (IInputStream fileStream = await file.OpenSequentialReadAsync())
                {
                    HttpStreamContent streamContent = new HttpStreamContent(fileStream);
                    form.Add(streamContent, "file", file.Name);

                    using (HttpClient client = new HttpClient())
                    {
                        using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, new Uri("localhost/uploadFile.php")))
                        {
                            request.Content = form;
                            HttpResponseMessage response =  await client.SendRequestAsync(request);
                            Debug.WriteLine("\nRequest: " + request.ToString());
                            Debug.WriteLine("\n\nResponse: " + response.ToString());
                        }
                    }
                }
            }
            return true;
   }
   catch (Exception e)
   {
       Debug.WriteLine(e.Message);
       return false;
   }
}

uploadFile.php

<?php
$uploaddir = 'uploads/';
$uploadedFile = $uploaddir . basename($_FILES['file']['name']);

if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadedFile)){
    echo 'File upload success!';
} else {
    echo 'Possible file upload attack!';
}
?>

The problem is when I try to upload a file, it threw me an error The object has been closed. (Exception from HRESULT: 0X80000013) and Exception thrown: 'System.ObjectDisposedException' in mscorlib.ni.dll.. I don't understand, I do the file uploading inside the using statement, how can it is disposed? Am I doing something wrong?

The debug shows me this

Request: Method: POST, RequestUri: 'http://localhost/uploadFile.php', Content: Windows.Web.Http.HttpMultipartFormDataContent, TransportInformation: ServerCertificate: '', ServerCertificateErrorSeverity: None, ServerCertificateErrors: {}, ServerIntermediateCertificates:{}, Headers:{ Accept-Encoding: gzip, deflate }{ Content-Length: 27749, Content-Type: multipart/form-data; boundary=9955f08b-e82d-428b-82e1-3197e5011ccd }

Response: StatusCode: 200, ReasonPhrase: 'OK', Version: 2, Content: Windows.Web.Http.HttpStreamContent, Headers:{Connection: Keep-Alive, Server: Apache/2.4.18 (Ubuntu), Keep-Alive: timeout=5, max=100, Date: Sun, 06 Nov 2016 04:02:40 GMT}{ Content-Length: 28, Content-Type: text/html; charset=UTF-8}

c#
php
uwp
windows-10-universal
asked on Stack Overflow Nov 5, 2016 by dude • edited Nov 6, 2016 by dude

1 Answer

2

Using statement provides a convenient syntax that ensures the correct use of IDisposable objects. Simply to say, it helps you to execute the Dispose() method. So your code is equal to:

 HttpMultipartFormDataContent form = new HttpMultipartFormDataContent();               
 IInputStream fileStream = await file.OpenSequentialReadAsync();
 HttpStreamContent streamContent = new HttpStreamContent(fileStream);
 form.Add(streamContent, "file", file.Name);    
 HttpClient client = new HttpClient();             
 HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, new Uri("http://127.0.0.1:9096/hello.php"));
 request.Content = form;      
 HttpResponseMessage response = await client.SendRequestAsync(request);
 Debug.WriteLine("\nRequest: " + request.ToString());
 Debug.WriteLine("\n\nResponse: " + response.ToString());
 request.Dispose();
 client.Dispose();
 fileStream.Dispose();
 form.Dispose();

You will got the exception at form.Dispose(); code line. The reason is that HttpMultipartFormDataContent.Add method doesn't need dispose. In my opinion, it is not the unmanaged resource which doesn't need dispose, other methods of HttpMultipartFormDataContent class like ReadAsBufferAsync may need dispose.

Update your code as follows which will not throw the closed exception:

HttpMultipartFormDataContent form = new HttpMultipartFormDataContent();
using (IInputStream fileStream = await file.OpenSequentialReadAsync())
{
    HttpStreamContent streamContent = new HttpStreamContent(fileStream);
    form.Add(streamContent, "file", file.Name);

    using (HttpClient client = new HttpClient())
    {
        using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, new Uri("http://127.0.0.1:9096/hello.php")))
        {
            request.Content = form;
            HttpResponseMessage response = await client.SendRequestAsync(request);
            Debug.WriteLine("\nRequest: " + request.ToString());
            Debug.WriteLine("\n\nResponse: " + response.ToString());
        }
    }
}
answered on Stack Overflow Nov 7, 2016 by Sunteen Wu

User contributions licensed under CC BY-SA 3.0