Tach Leuz!
Bin schon lange am Googeln und finde es nicht...
Ich muss mit C# eine Datei hochladen. Auf dem Webserver gegenüber sitzt ein PHP-Skript.
Das PHP-Skript hat nach dem Upload ein paar filespezifische Variabeln und die Funktion move_uploaded_file(...) zur Verfügung, um das hochgeladene File vom Serverpfad /tmp/ weiter zu verarbeiten. Dies scheint nicht kompatibel dazu zu sein, wie System.Net.WebClient.UploadFile(...) arbeitet. Das Skript erhält die Variabeln nicht, und wo das File auf dem Server hingelegt wird, bleibt unklar.
Der C#-Code müsste eigentlich genau das machen, was ein Formular-Upload im Hintergrund macht, alle diese Einzelschritte.
Fragen:
Danke für Eure Erfahrung und Eure Tipps.
Smofi 8)
Ich google, also bin ich.
http://www.peterhofer.ch
Schau Dir die System.Net.HttpWebRequest Klasse in der Doku genauer an. Da kannst Du sämtliche Header-Infos setzen.
Grüsse
Hallo Cord,
thx für die Antwort 😁
Ich habe mich von Deinem Hinweis ermuntern lassen und genau recherchiert. Mit Hilfe von Ethereal habe ich Header verglichen: Soll (Formular) und Ist (mein C#-Code).
Bei HttpWebRequest habe ich Möglichkeiten gesehen, den Header zu verändern. Aber keine davon bewirkt explizit Boundaries und Mime Encapsulation.
Andererseits habe ich gesehen, dass die nächst "höhere" Klasse WebClient Boundaries schreibt und Mime Encapsulation vornimmt, aber wiederum habe ich keinen Weg gefunden, Details anzugeben, z.B. den Variablennamen, unter dem im Formular der Name der Uploaddatei gespeichert wird.
Also setze ich den HTTP-Header mit HttpWebRequest selber zusammen, so wie der Kollege hier:
http://www.codeproject.com/csharp/uploadfileex.asp
Es funktioniert jetzt, aber mir bleibt das unangenehme Gefühl zurück, ich hätte nicht alle Doku gefunden und meine Lösung sei zu kompliziert.
Mein Code ist also:
// HttpWebRequest mit Boundary
string boundary;
string fileFormName = "datei";
StringBuilder sb = new StringBuilder();
boundary = "----------" + DateTime.Now.Ticks.ToString("x");
// 1. Request generieren
HttpWebRequest hwr = (HttpWebRequest)WebRequest.Create(@"http://stud.hswlu.ch/mak/kmus/upload.php");
// 2. Content type, Methode und User Agent setzen
hwr.ContentType = "multipart/form-data; boundary=" + boundary;
hwr.Method = "POST";
hwr.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)";
// 3. Build up the post message header
sb.Append("--");
sb.Append(boundary);
sb.Append("\r\n");
sb.Append("Content-Disposition: form-data; name=\"");
sb.Append(fileFormName);
sb.Append("\"; filename=\"");
sb.Append("testfile.xml");
sb.Append("\"");
sb.Append("\r\n");
sb.Append("Content-Type: ");
sb.Append("text/xml");
sb.Append("\r\n");
sb.Append("\r\n");
string postHeader = sb.ToString();
byte[] postHeaderBytes = Encoding.UTF8.GetBytes(postHeader);
// 4. File Buffer / Header bilden
byte[] boundaryBytes =
Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
FileStream fileStream = new FileStream(@"D:\KMUSensor\testfile.xml",
FileMode.Open, FileAccess.Read);
long length = postHeaderBytes.Length + fileStream.Length +
boundaryBytes.Length;
hwr.ContentLength = length;
Stream requestStream = hwr.GetRequestStream();
// 5. Write out our post header
requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
// 6. Write out the file contents
byte[] buffer = new Byte[checked((uint)Math.Min(4096,
(int)fileStream.Length))];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
requestStream.Write(buffer, 0, bytesRead);
// 7. Write out the trailing boundary
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
...
...
Wenn ich das nicht grösstenteils hätte abschreiben können, hätte ich das nicht innert nützlicher Frist schreiben können. Deshalb meine ich, es gäbe Wrapperfunktionen dafür. Wie siehst Du das?
Gutes Neues Jahr an alle
Smofi 8)
Ich google, also bin ich.
http://www.peterhofer.ch
Ok, merci fürs Umformatieren 🙂
Ich google, also bin ich.
http://www.peterhofer.ch
Halli Hallo
nur um das Thema zu vervollständigen.
Der Upload einer Datei wie folgt.
public void UploadProjectImage(string Path)
{
try
{
string urlupload = "http://www.../upload.php";
WebClient Client = new WebClient();
WebProxy Proxy = new WebProxy();
if (UseProxy == true)
{
Proxy = new WebProxy(this.ProxyIp, ProxyPort);
Proxy.Credentials = new NetworkCredential(ProxyUser, ProxyPass);
Client.Proxy = Proxy;
}
// Nur notwendig für Geschützes Verzeichniss .htacces
Client.Credentials = new NetworkCredential(this.Username, this.Passwort);
Byte[] responseArray = Client.UploadFile(urlupload, "POST", Path);
if (System.Text.Encoding.ASCII.GetString(responseArray).TrimStart() != "OK")
{
System.Windows.Forms.MessageBox.Show("Die Daten konnten nicht übermittelt werden : " + System.Text.Encoding.ASCII.GetString(responseArray));
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
}
Da Die Datei nun mittels POST an das PHP Script übergeben wurde,
aber wir den Namen des Formularfeldes nicht kennen, wird einfach das $_FILE Array mit einer schleife durchlaufen.
PHP Script :
<?php
if(count($_FILES) > 0){
foreach($_FILES as $File){
//Echo "Kopiere Datei nach ./".$File['name'];
copy($File['tmp_name'],"./ProjektVorlagen/".$File['name']);
// Prüfen, ob die Datei exestiert
if(file_exists("./ProjektVorlagen/".$File['name'])){
ECHO "OK";
}else{ECHO "Error";}
}
}
?>