Laden...

Datei hochladen mit C# für PHP-Skript

Erstellt von smofi vor 17 Jahren Letzter Beitrag vor 16 Jahren 2.775 Views
S
smofi Themenstarter:in
3 Beiträge seit 2006
vor 17 Jahren
Datei hochladen mit C# für PHP-Skript

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:

  1. Funktioniert der MS-Webclient nicht mit Apache/PHP?
  2. Wenn ja, hat jemand ein Minimalbeispiel dazu? Bei den Minimalbeispielen, die ich finde, ist immer .asp gegenüber.
  3. Wenn nein, bleibt eine andere Lösung als HTTP-Header zu basteln und mit System.Net.HttpRequest zu senden? Gibt es z.B. eine Library?

Danke für Eure Erfahrung und Eure Tipps.
Smofi 8)


Ich google, also bin ich.
http://www.peterhofer.ch

C
1.215 Beiträge seit 2004
vor 17 Jahren

Schau Dir die System.Net.HttpWebRequest Klasse in der Doku genauer an. Da kannst Du sämtliche Header-Infos setzen.

Grüsse

S
smofi Themenstarter:in
3 Beiträge seit 2006
vor 17 Jahren

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

1.130 Beiträge seit 2005
vor 17 Jahren

Bitte das nächste Mal Punkt 6 beachten Wie poste ich richtig?

S
smofi Themenstarter:in
3 Beiträge seit 2006
vor 17 Jahren

Ok, merci fürs Umformatieren 🙂


Ich google, also bin ich.
http://www.peterhofer.ch

F
2 Beiträge seit 2006
vor 16 Jahren

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";}
}

}


?>