我正在开发Windows Phone 8应用程序。我想使用MIME类型multipart / form-data和名为“ userid = SOME_ID”的字符串数据的HTTP POST请求通过PHP Web服务上载SQLite数据库。
我不想使用HttpClient,RestSharp或MyToolkit之类的第三方库。我尝试了下面的代码,但没有上传文件,也没有给我任何错误。它在Android,PHP等中运行良好,因此Web服务中没有问题。下面是我给定的代码(用于WP8)。它出什么问题了?
我已经用谷歌搜索,但我并没有针对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(); }
我也尝试解决Windows 8中的问题,但也无法正常工作。
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(); } } } }
这是我最后的工作代码。我的Web服务需要一个文件(POST参数名称为“ file”)和一个字符串值(POST参数名称为“ 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; }
我非常感谢达琳·卢梭(Darin Rousseau)的帮助。