如何上传文件到服务器HTTP POST的multipart / form-data的 [英] How to upload file to server with HTTP POST multipart/form-data

查看:247
本文介绍了如何上传文件到服务器HTTP POST的multipart / form-data的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发的Windows Phone 8应用。我想用MIME类型的multipart / form-data的&放大器HTTP POST请求上传通过PHP Web服务SQLite数据库;字符串数据称为用户ID = SOME_ID。我不想使用第三方库HttpClient的一样,RestSharp或MyToolkit。我想下面的code,但它并没有将文件上传和放大器;也没有给我任何错误。它在Android中,PHP等做工精细所以在web服务没有问题。下面是我定的code(对于WP8)。这有什么错呢?

我GOOGLE了我的问题,但没有为我工作。我不是为WP8获得特定

异步无效MainPage_Loaded(对象发件人,RoutedEventArgs E)
{
    var文件=等待Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(数据库);
    //下面一行给我0字节的文件,为什么?我应该使用
    // IsolatedStorageFile代替StorageFile
    // var文件=等待ApplicationData.Current.LocalFolder.GetFileAsync(数据库);
    字节[] fileBytes = NULL;
    使用(VAR流=等待file.OpenReadAsync())
    {
        fileBytes =新的字节[stream.Size]
        使用(VAR读卡器=新的DataReader(流))
        {
            等待reader.LoadAsync((UINT)stream.Size);
            reader.ReadBytes(fileBytes);
        }
    }    // VAR解析度=等待HttpPost(Util.UPLOAD_BACKUP,fileBytes);
    HttpPost(fileBytes);
}私人无效HttpPost(字节[] 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的);
}私人无效GetRequestStreamCallback(IAsyncResult的asynchronousResult,字节[] POSTDATA)
{
    //不知道怎么传的userid = some_user_id
    HttpWebRequest的要求=(HttpWebRequest的)asynchronousResult.AsyncState;
    流postStream = request.EndGetRequestStream(asynchronousResult);
    postStream.Write(POSTDATA,0,postData.Length);
    postStream.Close();
    VAR asyncResult = request.BeginGetResponse(新的AsyncCallback(GetResponseCallback),请求);
}私人无效GetResponseCallback(IAsyncResult的asynchronousResult)
{
    HttpWebRequest的要求=(HttpWebRequest的)asynchronousResult.AsyncState;
    HttpWebResponse响应=(HttpWebResponse)request.EndGetResponse(asynchronousResult);
    流streamResponse = response.GetResponseStream();
    StreamReader的streamRead =新的StreamReader(streamResponse);
    字符串responseString = streamRead.ReadToEnd();
    streamResponse.Close();
    streamRead.Close();
    response.Close();
}

我也试图解决在Windows 8我的问题,但它也不能正常工作。

公共异步任务上传(字节[] fileBytes)
{
    使用(VAR的客户=新的HttpClient())
    {
        使用(VAR内容=新MultipartFormDataContent(上传----+ DateTime.Now.ToString(System.Globalization.CultureInfo.InvariantCulture)))
        {
            content.Add(新StreamContent(新的MemoryStream(fileBytes)));
            //不知道下面一行是真还是假
            content.Add(新的StringContent(用户ID = farhanW8));
            使用(VAR消息=等待client.PostAsync(http://www.myserver.com/upload.php,内容))
            {
                VAR输入=等待message.Content.ReadAsStringAsync();
            }
        }
    }
}


解决方案

下面是我的最终工作code。我的网络服务需要一个文件(POST参数名称为文件)及一个字符串值(POST参数名称是用户id)。

  ///<总结>
///点击上传备份应用程序栏按钮时发生。作者:法尔汉Ghumra
 ///< /总结>
私人异步无效btnUploadBackup_Click(对象发件人,EventArgs的发送)
{
    VAR DBFILE =等待ApplicationData.Current.LocalFolder.GetFileAsync(Util.DBNAME);
    VAR fileBytes =等待GetBytesAsync(DBFILE);
    VAR PARAMS =新词典<字符串,字符串> {{参数userid,9}};
    UploadFilesToServer(新的URI(Util.UPLOAD_BACKUP),则params,Path.GetFileName(dbFile.Path),应用程序/八位字节流,fileBytes);
}///<总结>
///创建HTTP POST请求和放大器;上传数据库服务器。作者:法尔汉Ghumra
///< /总结>
私人无效UploadFilesToServer(URI URI,字典<字符串,字符串>数据串文件名,串fileContentType,字节[] FILEDATA)
{
    串边界=----------+ DateTime.Now.Ticks.ToString(×);
    HttpWebRequest的HttpWebRequest的=(HttpWebRequest的)WebRequest.Create(URI);
    httpWebRequest.ContentType =的multipart / form-data的;边界=+边界;
    httpWebRequest.Method =POST;
    httpWebRequest.BeginGetRequestStream((结果)=>
    {
        尝试
        {
            HttpWebRequest的要求=(HttpWebRequest的)result.AsyncState;
            使用(流requestStream = request.EndGetRequestStream(结果))
            {
                WriteMultipartForm(requestStream,边界,数据,文件名,fileContentType,FILEDATA);
            }
            request.BeginGetResponse(一个= GT;
            {
                尝试
                {
                    变种响应= request.EndGetResponse(一);
                    变种responseStream = response.GetResponseStream();
                    使用(VAR SR =新的StreamReader(responseStream))
                    {
                        使用(StreamReader的StreamReader的=新的StreamReader(response.GetResponseStream()))
                        {
                            字符串responseString = streamReader.ReadToEnd();
                            // responseString是取决于你的web服务。
                            如果(responseString ==成功)
                            {
                                MessageBox.Show(备份成功存储在服务器上。);
                            }
                            其他
                            {
                                的MessageBox.show(,而在服务器上传备份时发生错误。);
                            }
                        }
                    }
                }
                赶上(例外)
                {                }
            }, 空值);
        }
        赶上(例外)
        {        }
    },HttpWebRequest的);
}///<总结>
///写多部分HTTP POST请求。作者:法尔汉Ghumra
///< /总结>
私人无效WriteMultipartForm(流S,串边界,字典<字符串,字符串>数据串文件名,串fileContentType,字节[] FILEDATA)
{
    ///第一个边界
    字节[] = boundarybytes Encoding.UTF8.GetBytes( - +边界+\\ r \\ n);
    ///最后边界。
    字节[] =拖车Encoding.UTF8.GetBytes(\\ r \\ N--+边界+ - \\ r \\ n);
    ///表单数据格式正确的
    字符串formdataTemplate =内容DIS-数据; NAME = \\{0} \\\\ r \\ n \\ r \\ n {1};
    ///表单数据文件上传,格式正确
    字符串fileheaderTemplate =内容DIS-数据; NAME = \\{0} \\;文件名= \\{1} \\; \\ r \\ nContent类型:{2} \\ r \\ n \\ r \\ n;    ///添加跟踪如果我们需要一个CRLF与否。
    布尔bNeedsCRLF = FALSE;    如果(数据!= NULL)
    {
        的foreach(在data.Keys字符串键)
        {
            ///如果我们需要删除一个CRLF,做到这一点。
            如果(bNeedsCRLF)
                WriteToStream(S,为\\ r \\ n);            ///写的边界。
            WriteToStream(S,boundarybytes);            ///写入密钥。
            WriteToStream(S,的String.Format(formdataTemplate,钥匙,数据[关键]));
            bNeedsCRLF = TRUE;
        }
    }    ///如果我们没有钥匙,我们并不需要一个CRLF。
    如果(bNeedsCRLF)
        WriteToStream(S,为\\ r \\ n);    WriteToStream(S,boundarybytes);
    WriteToStream(S,的String.Format(fileheaderTemplate,文件,文件名,fileContentType));
    ///将文件写入数据流中。
    WriteToStream(S,FILEDATA);
    WriteToStream(S,拖车);
}///<总结>
///写入字符串流。作者:法尔汉Ghumra
///< /总结>
私人无效WriteToStream(流S,串TXT)
{
    字节[]字节= Encoding.UTF8.GetBytes(TXT);
    s.Write(字节,0,bytes.Length);
}///<总结>
///写入字节数组流。作者:法尔汉Ghumra
///< /总结>
私人无效WriteToStream(流S,字节[]字节)
{
    s.Write(字节,0,bytes.Length);
}///<总结>
///从Stor​​ageFile返回字节数组。作者:法尔汉Ghumra
///< /总结>
私人异步任务<字节[]> GetBytesAsync(StorageFile文件)
{
    字节[] fileBytes = NULL;
    使用(VAR流=等待file.OpenReadAsync())
    {
        fileBytes =新的字节[stream.Size]
        使用(VAR读卡器=新的DataReader(流))
        {
            等待reader.LoadAsync((UINT)stream.Size);
            reader.ReadBytes(fileBytes);
        }
    }    返回fileBytes;
}

我非常感谢达林卢梭对我的帮助。

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 my problem but nothing works for me. I am 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();
            }
        }
    }
}

解决方案

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.

这篇关于如何上传文件到服务器HTTP POST的multipart / form-data的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆