2016-08-08 14 views
0

Ich bin auf der Suche nach dem besten Weg, um Dateien aus dem kompakten Framework über REST auf einen Server zu übertragen. Ich habe einen Webdienst, den ich mit der .net Web API erstellt habe. Ich habe mir verschiedene SO-Fragen und andere Seiten angeschaut, die mit dem Senden von Dateien zu tun hatten, aber keiner von ihnen scheint das zu tun, was ich brauche.Compact Framework - Datei über REST hochladen

Ich versuche, Mediendateien von WM 6 und 6.5-Geräten an meinen REST-Dienst zu senden. Während die meisten Dateien weniger als 300k sind, können ein paar wenige 2-10 oder so Megabyte sein. Hat jemand einige Schnipsel, die ich verwenden könnte, um diese Arbeit zu machen?

Danke!

+0

Können Sie angeben, was nicht mit den Vorschlägen zu den anderen Fragen/Websites zu arbeiten scheint? Ansonsten besteht die Möglichkeit, dass die Antworten hier auch nicht für Sie funktionieren. –

+0

Sicher - ich sah ein paar, wo sie xml oder Textdateien sendeten, die sie in eine Zeichenfolge serialisierten. Oder einige (wie protobuf), wo sie eine Datenstruktur in eine Datei serialisieren. Ich habe auch gesehen, wo sie ein mehrteiliges Protokoll verwenden, aber das kompakte Framework unterstützt das nicht. – Kyver

+0

Ich sehe, die meisten Beispiele beinhalten 'multipart/form-data'. Sie können das selbst programmieren, aber es ist in der Tat nicht nötig, wenn Sie nur eine Datei senden. Ich werde ein Beispiel veröffentlichen. –

Antwort

1

Ich denke, das ist das Minimum, eine Datei zu senden:

using (var fileStream = File.Open(@"\file.txt", FileMode.Open, FileAccess.Read, FileShare.Read)) 
{ 
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://www.destination.com/path"); 
    request.Method = "POST"; // or PUT, depending on what the server expects 
    request.ContentLength = fileStream.Length; // see the note below 
    using (var requestStream = request.GetRequestStream()) 
    { 
     int bytes; 
     byte[] buffer = new byte[1024]; // any reasonable buffer size will do 
     while ((bytes = fileStream.Read(buffer, 0, buffer.Length)) > 0) 
     { 
      requestStream.Write(buffer, 0, bytes); 
     } 
    } 

    try 
    { 
     using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
     { 

     } 
    } 
    catch (WebException ex) 
    { 
     // failure 
    } 
} 

Hinweis: HTTP eine Art und Weise muss wissen, wenn Sie auf „Fertig“ Senden von Daten sind. Es gibt drei Möglichkeiten, dies zu erreichen:

  • request.ContentLength Stellen wie im Beispiel verwendet, da wir die Größe der Datei kennen, bevor irgendetwas zu senden
  • Set request.SendChunked, Datenblocks einschließlich ihrer jeweiligen Größe zu schicken
  • Sie könnte auch setzen request.AllowWriteStreamBuffering zu einem In-Memory-Puffer schreiben, aber ich würde nicht empfehlen, so viel Speicher auf dem kompakten Framework zu verschwenden.
+0

Ich habe das versucht und stieß auf einige Probleme. Erstens, der CF-Anfrage-Stream erlaubt nur Char-Arrays. Ich konnte requestStream.BaseStream.Write verwenden. Ich bin mir jedoch nicht sicher, ob dies einen Fehler verursacht hat, da ich immer wieder einen internen Serverfehler von meiner REST-App bekomme ("Der entfernte Server hat einen Fehler zurückgegeben: (500) Interner Serverfehler."). Ich kann Postman verwenden, um Testdaten zu senden, und es funktioniert großartig, aber meine CF-Anwendung lässt den Server diesen Fehler zurückgeben. Das lässt mich denken, dass auf der CF-Seite etwas nicht stimmt. – Kyver

+0

Es gibt keine Beschränkung, die nur Char-Arrays auf der CF erlaubt (zumindest nicht auf 2.0 und 3.5). Ich denke, das Problem ist, dass Ihr Dienst erwartet, dass die Daten in einem bestimmten _format_ wie JSON oder XML gesendet werden, und wenn dies der Fall ist, müssen die Binärdaten codiert werden (dh mit Base64). –

+0

Ausgezeichnet, es funktioniert jetzt alles. Ich habe ein StreamWriter-Objekt für den RequestStream verwendet, das keine Byte-Arrays in Leseanweisungen akzeptiert (außerdem können Sie keine Objekte in CF verwenden, da es die späte Bindung nicht unterstützt). Ich wechselte zu einem Stream-Objekt, kein Problem. Was den Serverfehler betrifft, funktionierte es auf meinem lokalen Rechner während des Tests mit dem Postboten. Aufgrund eines Bereitstellungsproblems funktionierte es nicht live. Vielen Dank! – Kyver

Verwandte Themen