Ich entwickle Windows Phone 8 App. Ich möchte eine SQLite-Datenbank über einen PHP-Webdienst mithilfe einer HTTP-POST-Anforderung mit Multimart- / Formulardaten vom Typ MIME und einer Zeichenfolgendaten mit dem Namen "userid = SOME_ID" hochladen.
Ich möchte keine Bibliotheken von Drittanbietern wie HttpClient, RestSharp oder MyToolkit verwenden. Ich habe den folgenden Code ausprobiert, aber er lädt die Datei nicht hoch und gibt mir auch keine Fehler. Es funktioniert gut in Android, PHP usw., so dass es kein Problem im Webdienst gibt. Unten ist mein gegebener Code (für WP8). Was stimmt damit nicht?
Ich habe gegoogelt und werde nicht spezifisch für 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();
}
Ich habe auch versucht, mein Problem in Windows 8 zu lösen, aber es funktioniert auch nicht.
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();
}
}
}
}
quelle
var fileStream = new FileStream(filePath, FileMode.Open); form.Add(new StreamContent(fileStream), "profile_pic");
Hier ist mein endgültiger Arbeitscode. Mein Webdienst benötigte eine Datei (POST-Parametername war "Datei") und einen Zeichenfolgenwert (POST-Parametername war "Benutzer-ID").
/// <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; }
Ich bin Darin Rousseau sehr dankbar, dass sie mir geholfen hat.
quelle
Diese vereinfachte Version funktioniert auch.
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); }
Fügen Sie bei Bedarf zusätzliche erforderliche Header hinzu.
quelle
MultipartFormDataContent
erfolglosem Ringen funktionierte dieser Ansatz gut. Es ist weniger glamourös, aber wenn Sie eine detaillierte Kontrolle über die HTTP-Nachricht benötigen, ist dies eine gute Lösung.Ich habe ein bisschen herumgespielt und mir eine vereinfachte, allgemeinere Lösung ausgedacht:
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(); }; }
Sie können es so verwenden:
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);
Und im PHP-Skript können Sie Daten wie folgt verarbeiten:
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']);
quelle
Sie können diese Klasse verwenden:
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; } } }
benutze es:
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);
Beispielserver
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>'; }
quelle
Folgendes hat bei mir beim Senden der Datei als Multiform-Daten funktioniert:
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); } } } }
Der oben verwendete GetAuthenticatedHttpClient kann sein:
private HttpClient GetAuthenticatedHttpClient() { HttpClient httpClient = new HttpClient(); httpClient.BaseAddress = new Uri(<yourBaseURL>)); httpClient.DefaultRequestHeaders.Add("Token, <yourToken>); return httpClient; }
quelle
MultipartFormDataContent
Idee, es war das, wonach ich gesucht habe.Der folgende Code liest eine Datei, konvertiert sie in ein Byte-Array und sendet dann eine Anfrage an den Server.
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; }
quelle
Hallo Leute, nach einem Tag im Web habe ich endlich das Problem mit dem folgenden Quellcode gelöst. Ich hoffe, Ihnen helfen zu können
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; }
quelle
Hier ist ein mehrteiliger Datenbeitrag mit Basisauthentifizierung 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); }
quelle
Es funktioniert für Windows Phone 8.1. Sie können dies versuchen.
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); }
quelle
Für Personen, die nach 403 verbotenen Problemen suchen, während sie versuchen, in mehrteiliger Form hochzuladen, kann das Folgende hilfreich sein, da abhängig von der Serverkonfiguration MULTIPART_STRICT_ERROR "! @Eq 0" aufgrund falscher MultipartFormDataContent-Header angezeigt wird. Bitte beachten Sie, dass beide Imagetag- / Dateinamenvariablen Anführungszeichen ("") enthalten, z. B. Dateiname = "" myfile.png "".
MultipartFormDataContent form = new MultipartFormDataContent(); ByteArrayContent imageContent = new ByteArrayContent(fileBytes, 0, fileBytes.Length); imageContent.Headers.TryAddWithoutValidation("Content-Disposition", "form-data; name="+imagetag+"; filename="+filename); imageContent.Headers.TryAddWithoutValidation("Content-Type", "image / png"); form.Add(imageContent, imagetag, filename);
quelle
Ich wollte auch Sachen auf einen Server hochladen und es war eine Spring-Anwendung, bei der ich endlich entdeckte, dass ich tatsächlich einen Inhaltstyp festlegen musste, damit er als Datei interpretiert werden konnte. Genau wie dieser:
... MultipartFormDataContent form = new MultipartFormDataContent(); var fileStream = new FileStream(uniqueTempPathInProject, FileMode.Open); var streamContent = new StreamContent(fileStream); streamContent.Headers.ContentType=new MediaTypeHeaderValue("application/zip"); form.Add(streamContent, "file",fileName); ...
quelle
Top to @loop Antwort.
Wir haben den folgenden Fehler für Asp.Net MVC erhalten. Es kann keine Verbindung zum Remote-Server hergestellt werden
Fix: Nach dem Hinzufügen des folgenden Codes in Web.Confing wurde das Problem für uns behoben
<system.net> <defaultProxy useDefaultCredentials="true" > </defaultProxy> </system.net>
quelle
Ich weiß, dass dies ein alter Thread ist, aber ich habe damit gekämpft und möchte meine Lösung teilen.
Diese Lösung funktioniert mit
HttpClient
undMultipartFormDataContent
vonSystem.Net.Http
. Sie können es mit.NET Core 1.0
oder höher oder freigeben.NET Framework 4.5
oder höher .Kurz zusammengefasst handelt es sich um eine asynchrone Methode, die als Parameter die URL empfängt, unter der Sie den POST ausführen möchten, eine Schlüssel- / Wertsammlung zum Senden von Zeichenfolgen und eine Schlüssel- / Wertsammlung zum Senden von Dateien.
private static async Task<HttpResponseMessage> Post(string url, NameValueCollection strings, NameValueCollection files) { var formContent = new MultipartFormDataContent(/* If you need a boundary, you can define it here */); // Strings foreach (string key in strings.Keys) { string inputName = key; string content = strings[key]; formContent.Add(new StringContent(content), inputName); } // Files foreach (string key in files.Keys) { string inputName = key; string fullPathToFile = files[key]; FileStream fileStream = File.OpenRead(fullPathToFile); var streamContent = new StreamContent(fileStream); var fileContent = new ByteArrayContent(streamContent.ReadAsByteArrayAsync().Result); formContent.Add(fileContent, inputName, Path.GetFileName(fullPathToFile)); } var myHttpClient = new HttpClient(); var response = await myHttpClient.PostAsync(url, formContent); //string stringContent = await response.Content.ReadAsStringAsync(); // If you need to read the content return response; }
Sie können Ihren POST folgendermaßen vorbereiten (Sie können so viele Zeichenfolgen und Dateien hinzufügen, wie Sie benötigen):
string url = @"http://yoursite.com/upload.php" NameValueCollection strings = new NameValueCollection(); strings.Add("stringInputName1", "The content for input 1"); strings.Add("stringInputNameN", "The content for input N"); NameValueCollection files = new NameValueCollection(); files.Add("fileInputName1", @"FullPathToFile1"); // Path + filename files.Add("fileInputNameN", @"FullPathToFileN");
Und schließlich rufen Sie die Methode folgendermaßen auf:
var result = Post(url, strings, files).GetAwaiter().GetResult();
Wenn Sie möchten, können Sie Ihren Statuscode überprüfen und den Grund wie folgt angeben:
if (result.StatusCode == HttpStatusCode.OK) { // Logic if all was OK } else { // You can show a message like this: Console.WriteLine(string.Format("Error. StatusCode: {0} | ReasonPhrase: {1}", result.StatusCode, result.ReasonPhrase)); }
Und wenn jemand es braucht, lasse ich hier ein kleines Beispiel, wie man eine Datei mit PHP speichert (auf der anderen Seite unserer .Net-App):
<?php if (isset($_FILES['fileInputName1']) && $_FILES['fileInputName1']['error'] === UPLOAD_ERR_OK) { $fileTmpPath = $_FILES['fileInputName1']['tmp_name']; $fileName = $_FILES['fileInputName1']['name']; move_uploaded_file($fileTmpPath, '/the/final/path/you/want/' . $fileName); }
Ich hoffe, Sie finden es nützlich, ich bin aufmerksam auf Ihre Fragen.
quelle
Async().Result
ist nicht asynchronstreamContent.ReadAsByteArrayAsync().Result
.GetAwaiter().GetResult()