كيفية تحميل الملف إلى الخادم باستخدام HTTP POST متعدد الأجزاء / بيانات النموذج؟

سئل على ١٣ نوفمبر ٢٠١٣  ·  تمت مشاهدة 262k مرة  ·  مصدر

Farhan Ghumra picture
في ١٣ نوفمبر ٢٠١٣

أقوم بتطوير تطبيق Windows Phone 8. أرغب في تحميل قاعدة بيانات SQLite عبر خدمة ويب PHP باستخدام طلب HTTP POST مع بيانات نموذجية / متعددة الأجزاء من نوع MIME وبيانات سلسلة تسمى "userid = SOME_ID".

لا أريد استخدام libs لجهة خارجية مثل HttpClient أو RestSharp أو MyToolkit. لقد جربت الكود أدناه ولكنه لا يقوم بتحميل الملف ولا يعطيني أي أخطاء. إنها تعمل بشكل جيد في Android و PHP وما إلى ذلك ، لذا لا توجد مشكلة في خدمة الويب. يوجد أدناه الكود الخاص بي (لـ WP8). ما الخطأ فى ذلك؟

لقد بحثت في google ولم أحصل على معلومات محددة عن 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();
            }
        }
    }
}

الإجابات

loop picture
في ١٤ نوفمبر ٢٠١٣
146

التنفيذ الأساسي باستخدام 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;
Farhan Ghumra picture
في ١٥ نوفمبر ٢٠١٣
27

هذا هو رمز عملي النهائي. احتاجت خدمة الويب الخاصة بي إلى ملف واحد (اسم معلمة POST كان "ملف") وقيمة سلسلة (اسم معلمة 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;
}

أنا ممتن جدًا لدارين روسو لمساعدتي.

Wolf5 picture
في ١٨ مارس ٢٠١٥
22

هذه النسخة المبسطة تعمل أيضًا.

public void UploadMultipart(byte[] file, string filename, string contentType, string url)
{
    var webClient = new WebClient();
    string boundary = "------------------------" + DateTime.Now.Ticks.ToString("x");
    webClient.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);
    var fileData = webClient.Encoding.GetString(file);
    var package = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"file\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n{3}\r\n--{0}--\r\n", boundary, filename, contentType, fileData);

    var nfile = webClient.Encoding.GetBytes(package);

    byte[] resp = webClient.UploadData(url, "POST", nfile);
}

أضف أي رؤوس إضافية مطلوبة إذا لزم الأمر.

Hockic picture
في ١٤ ديسمبر ٢٠١٤
13

كنت ألعب قليلاً وتوصلت إلى حل مبسط وأكثر عمومية:

private static string sendHttpRequest(string url, NameValueCollection values, NameValueCollection files = null)
{
    string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
    // The first boundary
    byte[] boundaryBytes = System.Text.Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
    // The last boundary
    byte[] trailer = System.Text.Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
    // The first time it itereates, we need to make sure it doesn't put too many new paragraphs down or it completely messes up poor webbrick
    byte[] boundaryBytesF = System.Text.Encoding.ASCII.GetBytes("--" + boundary + "\r\n");

    // Create the request and set parameters
    HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
    request.ContentType = "multipart/form-data; boundary=" + boundary;
    request.Method = "POST";
    request.KeepAlive = true;
    request.Credentials = System.Net.CredentialCache.DefaultCredentials;

    // Get request stream
    Stream requestStream = request.GetRequestStream();

    foreach (string key in values.Keys)
    {
        // Write item to stream
        byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}", key, values[key]));
        requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
        requestStream.Write(formItemBytes, 0, formItemBytes.Length);
    }

    if (files != null)
    { 
        foreach(string key in files.Keys)
        {
            if(File.Exists(files[key]))
            {
                int bytesRead = 0;
                byte[] buffer = new byte[2048];
                byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n", key, files[key]));
                requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
                requestStream.Write(formItemBytes, 0, formItemBytes.Length);

                using (FileStream fileStream = new FileStream(files[key], FileMode.Open, FileAccess.Read))
                {
                    while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                    {
                        // Write file content to stream, byte by byte
                        requestStream.Write(buffer, 0, bytesRead);
                    }

                    fileStream.Close();
                }
            }
        }
    }

    // Write trailer and close stream
    requestStream.Write(trailer, 0, trailer.Length);
    requestStream.Close();

    using (StreamReader reader = new StreamReader(request.GetResponse().GetResponseStream()))
    {
        return reader.ReadToEnd();
    };
}

يمكنك استخدامه على النحو التالي:

string fileLocation = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + Path.DirectorySeparatorChar + "somefile.jpg";
NameValueCollection values = new NameValueCollection();
NameValueCollection files = new NameValueCollection();
values.Add("firstName", "Alan");
files.Add("profilePicture", fileLocation);
sendHttpRequest("http://example.com/handler.php", values, files);

وفي نص PHP يمكنك التعامل مع بيانات مثل هذا:

echo $_POST['firstName'];
$name = $_POST['firstName'];
$image = $_FILES['profilePicture'];
$ds = DIRECTORY_SEPARATOR;
move_uploaded_file($image['tmp_name'], realpath(dirname(__FILE__)) . $ds . "uploads" . $ds . $image['name']);
woondark picture
في ٢ ديسمبر ٢٠١٣
10

يمكنك استخدام هذه الفئة:

using System.Collections.Specialized;
class Post_File
{
    public static void HttpUploadFile(string url, string file, string paramName, string contentType, NameValueCollection nvc)
    {
        string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
        byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
        byte[] boundarybytesF = System.Text.Encoding.ASCII.GetBytes("--" + boundary + "\r\n");  // the first time it itereates, you need to make sure it doesn't put too many new paragraphs down or it completely messes up poor webbrick.  


        HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
        wr.Method = "POST";
        wr.KeepAlive = true;
        wr.Credentials = System.Net.CredentialCache.DefaultCredentials;
        wr.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        var nvc2 = new NameValueCollection();
        nvc2.Add("Accepts-Language", "en-us,en;q=0.5");
        wr.Headers.Add(nvc2);
        wr.ContentType = "multipart/form-data; boundary=" + boundary;


        Stream rs = wr.GetRequestStream();

        bool firstLoop = true;
        string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
        foreach (string key in nvc.Keys)
        {
            if (firstLoop)
            {
                rs.Write(boundarybytesF, 0, boundarybytesF.Length);
                firstLoop = false;
            }
            else
            {
                rs.Write(boundarybytes, 0, boundarybytes.Length);
            }
            string formitem = string.Format(formdataTemplate, key, nvc[key]);
            byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
            rs.Write(formitembytes, 0, formitembytes.Length);
        }
        rs.Write(boundarybytes, 0, boundarybytes.Length);

        string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
        string header = string.Format(headerTemplate, paramName, new FileInfo(file).Name, contentType);
        byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
        rs.Write(headerbytes, 0, headerbytes.Length);

        FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
        byte[] buffer = new byte[4096];
        int bytesRead = 0;
        while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
        {
            rs.Write(buffer, 0, bytesRead);
        }
        fileStream.Close();

        byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
        rs.Write(trailer, 0, trailer.Length);
        rs.Close();

        WebResponse wresp = null;
        try
        {
            wresp = wr.GetResponse();
            Stream stream2 = wresp.GetResponseStream();
            StreamReader reader2 = new StreamReader(stream2);
        }
        catch (Exception ex)
        {
            if (wresp != null)
            {
                wresp.Close();
                wresp = null;
            }
        }
        finally
        {
            wr = null;
        }
    }
}

استخدمه:

NameValueCollection nvc = new NameValueCollection();
//nvc.Add("id", "TTR");
nvc.Add("table_name", "uploadfile");
nvc.Add("commit", "uploadfile");
Post_File.HttpUploadFile("http://example/upload_file.php", @"C:\user\yourfile.docx", "uploadfile", "application/vnd.ms-excel", nvc);

خادم المثال upload_file.php :

m('File upload '.(@copy($_FILES['uploadfile']['tmp_name'],getcwd().'\\'.'/'.$_FILES['uploadfile']['name']) ? 'success' : 'failed'));
function m($msg) {
    echo '<div style="background:#f1f1f1;border:1px solid #ddd;padding:15px;font:14px;text-align:center;font-weight:bold;">';
    echo $msg;
    echo '</div>';
}
Raghav picture
في ٨ أكتوبر ٢٠١٩
4

إليك ما نجح معي أثناء إرسال الملف كبيانات متعددة النماذج:

    public T HttpPostMultiPartFileStream<T>(string requestURL, string filePath, string fileName)
    {
        string content = null;

        using (MultipartFormDataContent form = new MultipartFormDataContent())
        {
            StreamContent streamContent;
            using (var fileStream = new FileStream(filePath, FileMode.Open))
            {
                streamContent = new StreamContent(fileStream);

                streamContent.Headers.Add("Content-Type", "application/octet-stream");
                streamContent.Headers.Add("Content-Disposition", string.Format("form-data; name=\"file\"; filename=\"{0}\"", fileName));
                form.Add(streamContent, "file", fileName);

                using (HttpClient client = GetAuthenticatedHttpClient())
                {
                    HttpResponseMessage response = client.PostAsync(requestURL, form).GetAwaiter().GetResult();
                    content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();



                    try
                    {
                        return JsonConvert.DeserializeObject<T>(content);
                    }
                    catch (Exception ex)
                    {
                        // Log the exception
                    }

                    return default(T);
                }
            }
        }
    }

يمكن أن يكون GetAuthenticatedHttpClient المستخدم أعلاه:

private HttpClient GetAuthenticatedHttpClient()
{
    HttpClient httpClient = new HttpClient();
    httpClient.BaseAddress = new Uri(<yourBaseURL>));
    httpClient.DefaultRequestHeaders.Add("Token, <yourToken>);
    return httpClient;
}
Siddarth Kanted picture
في ١٨ مايو ٢٠١٧
2

يقرأ الكود أدناه ملفًا ، ويحوله إلى مصفوفة بايت ، ثم يقدم طلبًا إلى الخادم.

    public void PostImage()
    {
        HttpClient httpClient = new HttpClient();
        MultipartFormDataContent form = new MultipartFormDataContent();

        byte[] imagebytearraystring = ImageFileToByteArray(@"C:\Users\Downloads\icon.png");
        form.Add(new ByteArrayContent(imagebytearraystring, 0, imagebytearraystring.Count()), "profile_pic", "hello1.jpg");
        HttpResponseMessage response = httpClient.PostAsync("your url", form).Result;

        httpClient.Dispose();
        string sd = response.Content.ReadAsStringAsync().Result;
    }

    private byte[] ImageFileToByteArray(string fullFilePath)
    {
        FileStream fs = File.OpenRead(fullFilePath);
        byte[] bytes = new byte[fs.Length];
        fs.Read(bytes, 0, Convert.ToInt32(fs.Length));
        fs.Close();
        return bytes;
    }
Ali Sadri picture
في ٢٨ يناير ٢٠١٩
1

مرحبًا يا رفاق بعد البحث على الويب يومًا واحدًا ، أخيرًا ، حللت المشكلة باستخدام الكود المصدري أدناه وآمل أن أساعدك

    public UploadResult UploadFile(string  fileAddress)
    {
        HttpClient client = new HttpClient();

        MultipartFormDataContent form = new MultipartFormDataContent();
        HttpContent content = new StringContent("fileToUpload");
        form.Add(content, "fileToUpload");       
        var stream = new FileStream(fileAddress, FileMode.Open);            
        content = new StreamContent(stream);
        var fileName = 
        content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
        {
            Name = "name",
            FileName = Path.GetFileName(fileAddress),                 
        };
        form.Add(content);
        HttpResponseMessage response = null;          

        var url = new Uri("http://192.168.10.236:2000/api/Upload2");
        response = (client.PostAsync(url, form)).Result;          

    }
Rajitha picture
في ١٥ نوفمبر ٢٠١٩
1

هنا منشور بيانات متعدد الأجزاء مع المصادقة الأساسية C #

public string UploadFilesToRemoteUrl(string url)
    {
        try
        {                             

            Dictionary<string, object> formFields = new Dictionary<string, object>();
            formFields.Add("requestid", "{\"id\":\"idvalue\"}");

            string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.ContentType = "multipart/form-data; boundary=" + boundary;

            // basic authentication.
            var username = "userid";
            var password = "password";

            string credidentials = username + ":" + password;
            var authorization = Convert.ToBase64String(Encoding.Default.GetBytes(credidentials));
            request.Headers["Authorization"] = "Basic " + authorization;

            request.Method = "POST";
            request.KeepAlive = true;

            Stream memStream = new System.IO.MemoryStream();
            WriteFormData(formFields, memStream, boundary);

            FileInfo fileToUpload = new FileInfo(@"filelocation with name");
            string fileFormKey = "file";
            if (fileToUpload != null)
            {
                WritefileToUpload(fileToUpload, memStream, boundary, fileFormKey);
            }
            request.ContentLength = memStream.Length;

            using (Stream requestStream = request.GetRequestStream())
            {
                memStream.Position = 0;
                byte[] tempBuffer = new byte[memStream.Length];
                memStream.Read(tempBuffer, 0, tempBuffer.Length);
                memStream.Close();
                requestStream.Write(tempBuffer, 0, tempBuffer.Length);
            }

            using (var response = request.GetResponse())
            {
                Stream responseSReam = response.GetResponseStream();
                StreamReader streamReader = new StreamReader(responseSReam);
                return streamReader.ReadToEnd();
            }
        }
        catch (WebException ex)
        {
            using (WebResponse response = ex.Response)
            {
                HttpWebResponse httpResponse = (HttpWebResponse)response;
                using (var streamReader = new StreamReader(response.GetResponseStream()))
                    return streamReader.ReadToEnd();

            }
        }
    }

    // write form id.
    public static void WriteFormData(Dictionary<string, object> dictionary, Stream stream, string mimeBoundary)
    {
        string formdataTemplate = "\r\n--" + mimeBoundary +
                                    "\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
        if (dictionary != null)
        {
            foreach (string key in dictionary.Keys)
            {
                string formitem = string.Format(formdataTemplate, key, dictionary[key]);
                byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
                stream.Write(formitembytes, 0, formitembytes.Length);
            }
        }
    }

    // write file.
    public static void WritefileToUpload(FileInfo file, Stream stream, string mimeBoundary, string formkey)
    {
        var boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + mimeBoundary + "\r\n");
        var endBoundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + mimeBoundary + "--");

        string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" +
                                "Content-Type: application/octet-stream\r\n\r\n";

        stream.Write(boundarybytes, 0, boundarybytes.Length);
        var header = string.Format(headerTemplate, formkey, file.Name);
        var headerbytes = System.Text.Encoding.UTF8.GetBytes(header);

        stream.Write(headerbytes, 0, headerbytes.Length);

        using (var fileStream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read))
        {
            var buffer = new byte[1024];
            var bytesRead = 0;
            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
            {
                stream.Write(buffer, 0, bytesRead);
            }
        }
        stream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
    } 
reza.cse08 picture
في ١٤ نوفمبر ٢٠١٥
0

يعمل مع هاتف windows 8.1. يمكنك تجربة هذا.

Dictionary<string, object> _headerContents = new Dictionary<string, object>();
const String _lineEnd = "\r\n";
const String _twoHyphens = "--";
const String _boundary = "*****";
private async void UploadFile_OnTap(object sender, System.Windows.Input.GestureEventArgs e)
{
   Uri serverUri = new Uri("http:www.myserver.com/Mp4UploadHandler", UriKind.Absolute);    
   string fileContentType = "multipart/form-data";       
   byte[] _boundarybytes = Encoding.UTF8.GetBytes(_twoHyphens + _boundary + _lineEnd);
   byte[] _trailerbytes = Encoding.UTF8.GetBytes(_twoHyphens + _boundary + _twoHyphens + _lineEnd);
   Dictionary<string, object> _headerContents = new Dictionary<string, object>();
   SetEndHeaders();  // to add some extra parameter if you need

   httpWebRequest = (HttpWebRequest)WebRequest.Create(serverUri);
   httpWebRequest.ContentType = fileContentType + "; boundary=" + _boundary;
   httpWebRequest.Method = "POST";
   httpWebRequest.AllowWriteStreamBuffering = false;  // get response after upload header part

   var fileName = Path.GetFileName(MediaStorageFile.Path);    
   Stream fStream = (await MediaStorageFile.OpenAsync(Windows.Storage.FileAccessMode.Read)).AsStream(); //MediaStorageFile is a storage file from where you want to upload the file of your device    
   string fileheaderTemplate = "Content-Disposition: form-data; name=\"{0}\"" + _lineEnd + _lineEnd + "{1}" + _lineEnd;    
   long httpLength = 0;
   foreach (var headerContent in _headerContents) // get the length of upload strem
   httpLength += _boundarybytes.Length + Encoding.UTF8.GetBytes(string.Format(fileheaderTemplate, headerContent.Key, headerContent.Value)).Length;

   httpLength += _boundarybytes.Length + Encoding.UTF8.GetBytes("Content-Disposition: form-data; name=\"uploadedFile\";filename=\"" + fileName + "\"" + _lineEnd).Length
                                       + Encoding.UTF8.GetBytes(_lineEnd).Length * 2 + _trailerbytes.Length;
   httpWebRequest.ContentLength = httpLength + fStream.Length;  // wait until you upload your total stream 

    httpWebRequest.BeginGetRequestStream((result) =>
    {
       try
       {
         HttpWebRequest request = (HttpWebRequest)result.AsyncState;
         using (Stream stream = request.EndGetRequestStream(result))
         {
            foreach (var headerContent in _headerContents)
            {
               WriteToStream(stream, _boundarybytes);
               WriteToStream(stream, string.Format(fileheaderTemplate, headerContent.Key, headerContent.Value));
             }

             WriteToStream(stream, _boundarybytes);
             WriteToStream(stream, "Content-Disposition: form-data; name=\"uploadedFile\";filename=\"" + fileName + "\"" + _lineEnd);
             WriteToStream(stream, _lineEnd);

             int bytesRead = 0;
             byte[] buffer = new byte[2048];  //upload 2K each time

             while ((bytesRead = fStream.Read(buffer, 0, buffer.Length)) != 0)
             {
               stream.Write(buffer, 0, bytesRead);
               Array.Clear(buffer, 0, 2048); // Clear the array.
              }

              WriteToStream(stream, _lineEnd);
              WriteToStream(stream, _trailerbytes);
              fStream.Close();
         }
         request.BeginGetResponse(a =>
         { //get response here
            try
            {
               var response = request.EndGetResponse(a);
               using (Stream streamResponse = response.GetResponseStream())
               using (var memoryStream = new MemoryStream())
               {   
                   streamResponse.CopyTo(memoryStream);
                   responseBytes = memoryStream.ToArray();  // here I get byte response from server. you can change depends on server response
               }    
              if (responseBytes.Length > 0 && responseBytes[0] == 1)
                 MessageBox.Show("Uploading Completed");
              else
                  MessageBox.Show("Uploading failed, please try again.");
            }
            catch (Exception ex)
            {}
          }, null);
      }
      catch (Exception ex)
      {
         fStream.Close();                             
      }
   }, httpWebRequest);
}

private static void WriteToStream(Stream s, string txt)
{
   byte[] bytes = Encoding.UTF8.GetBytes(txt);
   s.Write(bytes, 0, bytes.Length);
 }

 private static void WriteToStream(Stream s, byte[] bytes)
 {
   s.Write(bytes, 0, bytes.Length);
 }

 private void SetEndHeaders()
 {
   _headerContents.Add("sId", LocalData.currentUser.SessionId);
   _headerContents.Add("uId", LocalData.currentUser.UserIdentity);
   _headerContents.Add("authServer", LocalData.currentUser.AuthServerIP);
   _headerContents.Add("comPort", LocalData.currentUser.ComPort);
 }