I am developing Windows Phone 8 app. I want to upload SQLite database via PHP web service using HTTP POST request with MIME type multipart/form-data & a string data called "userid=SOME_ID".
I don't want to use 3rd party libs like HttpClient, RestSharp or MyToolkit. I tried the below code but it doesn't upload the file & also doesn't give me any errors. It's working fine in Android, PHP, etc so there's no issue in web service. Below is my given code (for WP8). what's wrong with it?
I've googled and I'm not getting specific for WP8
async void MainPage_Loaded(object sender, RoutedEventArgs e) { var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(DBNAME); //Below line gives me file with 0 bytes, why? Should I use //IsolatedStorageFile instead of StorageFile //var file = await ApplicationData.Current.LocalFolder.GetFileAsync(DBNAME); byte[] fileBytes = null; using (var stream = await file.OpenReadAsync()) { fileBytes = new byte[stream.Size]; using (var reader = new DataReader(stream)) { await reader.LoadAsync((uint)stream.Size); reader.ReadBytes(fileBytes); } } //var res = await HttpPost(Util.UPLOAD_BACKUP, fileBytes); HttpPost(fileBytes); } private void HttpPost(byte[] file_bytes) { HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("http://www.myserver.com/upload.php"); httpWebRequest.ContentType = "multipart/form-data"; httpWebRequest.Method = "POST"; var asyncResult = httpWebRequest.BeginGetRequestStream((ar) => { GetRequestStreamCallback(ar, file_bytes); }, httpWebRequest); } private void GetRequestStreamCallback(IAsyncResult asynchronousResult, byte[] postData) { //DON'T KNOW HOW TO PASS "userid=some_user_id" HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; Stream postStream = request.EndGetRequestStream(asynchronousResult); postStream.Write(postData, 0, postData.Length); postStream.Close(); var asyncResult = request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request); } private void GetResponseCallback(IAsyncResult asynchronousResult) { HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult); Stream streamResponse = response.GetResponseStream(); StreamReader streamRead = new StreamReader(streamResponse); string responseString = streamRead.ReadToEnd(); streamResponse.Close(); streamRead.Close(); response.Close(); }
I also tried to solve my problem in Windows 8 but it's also not working.
public async Task Upload(byte[] fileBytes) { using (var client = new HttpClient()) { using (var content = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(System.Globalization.CultureInfo.InvariantCulture))) { content.Add(new StreamContent(new MemoryStream(fileBytes))); //Not sure below line is true or not content.Add(new StringContent("userid=farhanW8")); using (var message = await client.PostAsync("http://www.myserver.com/upload.php", content)) { var input = await message.Content.ReadAsStringAsync(); } } } }
Follow this rules when creating a multipart form: Specify enctype="multipart/form-data" attribute on a form tag. Add a name attribute to a single input type="file" tag. DO NOT add a name attribute to any other input, select or textarea tags.
Multipart upload allows you to upload a single object as a set of parts. Each part is a contiguous portion of the object's data. You can upload these object parts independently and in any order. If transmission of any part fails, you can retransmit that part without affecting other parts.
mime type... xmlHttpRequest. open('POST', target, true); xmlHttpRequest.
Basic implementation using MultipartFormDataContent :-
HttpClient httpClient = new HttpClient(); MultipartFormDataContent form = new MultipartFormDataContent(); form.Add(new StringContent(username), "username"); form.Add(new StringContent(useremail), "email"); form.Add(new StringContent(password), "password"); form.Add(new ByteArrayContent(file_bytes, 0, file_bytes.Length), "profile_pic", "hello1.jpg"); HttpResponseMessage response = await httpClient.PostAsync("PostUrl", form); response.EnsureSuccessStatusCode(); httpClient.Dispose(); string sd = response.Content.ReadAsStringAsync().Result;
Here's my final working code. My web service needed one file (POST parameter name was "file") & a string value (POST parameter name was "userid").
/// <summary> /// Occurs when upload backup application bar button is clicked. Author : Farhan Ghumra /// </summary> private async void btnUploadBackup_Click(object sender, EventArgs e) { var dbFile = await ApplicationData.Current.LocalFolder.GetFileAsync(Util.DBNAME); var fileBytes = await GetBytesAsync(dbFile); var Params = new Dictionary<string, string> { { "userid", "9" } }; UploadFilesToServer(new Uri(Util.UPLOAD_BACKUP), Params, Path.GetFileName(dbFile.Path), "application/octet-stream", fileBytes); } /// <summary> /// Creates HTTP POST request & uploads database to server. Author : Farhan Ghumra /// </summary> private void UploadFilesToServer(Uri uri, Dictionary<string, string> data, string fileName, string fileContentType, byte[] fileData) { string boundary = "----------" + DateTime.Now.Ticks.ToString("x"); HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri); httpWebRequest.ContentType = "multipart/form-data; boundary=" + boundary; httpWebRequest.Method = "POST"; httpWebRequest.BeginGetRequestStream((result) => { try { HttpWebRequest request = (HttpWebRequest)result.AsyncState; using (Stream requestStream = request.EndGetRequestStream(result)) { WriteMultipartForm(requestStream, boundary, data, fileName, fileContentType, fileData); } request.BeginGetResponse(a => { try { var response = request.EndGetResponse(a); var responseStream = response.GetResponseStream(); using (var sr = new StreamReader(responseStream)) { using (StreamReader streamReader = new StreamReader(response.GetResponseStream())) { string responseString = streamReader.ReadToEnd(); //responseString is depend upon your web service. if (responseString == "Success") { MessageBox.Show("Backup stored successfully on server."); } else { MessageBox.Show("Error occurred while uploading backup on server."); } } } } catch (Exception) { } }, null); } catch (Exception) { } }, httpWebRequest); } /// <summary> /// Writes multi part HTTP POST request. Author : Farhan Ghumra /// </summary> private void WriteMultipartForm(Stream s, string boundary, Dictionary<string, string> data, string fileName, string fileContentType, byte[] fileData) { /// The first boundary byte[] boundarybytes = Encoding.UTF8.GetBytes("--" + boundary + "\r\n"); /// the last boundary. byte[] trailer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n"); /// the form data, properly formatted string formdataTemplate = "Content-Dis-data; name=\"{0}\"\r\n\r\n{1}"; /// the form-data file upload, properly formatted string fileheaderTemplate = "Content-Dis-data; name=\"{0}\"; filename=\"{1}\";\r\nContent-Type: {2}\r\n\r\n"; /// Added to track if we need a CRLF or not. bool bNeedsCRLF = false; if (data != null) { foreach (string key in data.Keys) { /// if we need to drop a CRLF, do that. if (bNeedsCRLF) WriteToStream(s, "\r\n"); /// Write the boundary. WriteToStream(s, boundarybytes); /// Write the key. WriteToStream(s, string.Format(formdataTemplate, key, data[key])); bNeedsCRLF = true; } } /// If we don't have keys, we don't need a crlf. if (bNeedsCRLF) WriteToStream(s, "\r\n"); WriteToStream(s, boundarybytes); WriteToStream(s, string.Format(fileheaderTemplate, "file", fileName, fileContentType)); /// Write the file data to the stream. WriteToStream(s, fileData); WriteToStream(s, trailer); } /// <summary> /// Writes string to stream. Author : Farhan Ghumra /// </summary> private void WriteToStream(Stream s, string txt) { byte[] bytes = Encoding.UTF8.GetBytes(txt); s.Write(bytes, 0, bytes.Length); } /// <summary> /// Writes byte array to stream. Author : Farhan Ghumra /// </summary> private void WriteToStream(Stream s, byte[] bytes) { s.Write(bytes, 0, bytes.Length); } /// <summary> /// Returns byte array from StorageFile. Author : Farhan Ghumra /// </summary> private async Task<byte[]> GetBytesAsync(StorageFile file) { byte[] fileBytes = null; using (var stream = await file.OpenReadAsync()) { fileBytes = new byte[stream.Size]; using (var reader = new DataReader(stream)) { await reader.LoadAsync((uint)stream.Size); reader.ReadBytes(fileBytes); } } return fileBytes; }
I am very much thankful to Darin Rousseau for helping me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With