Hochladen/Herunterladen von Byte-Arrays, die mit AngularJS und ASP.NET Web-API

Ich habe mehrere Tage recherchieren und arbeiten an einer Lösung für das hochladen/herunterladen von byte[]'s. Ich bin in der Nähe, aber haben ein verbleibendes Problem zu sein scheint in meinem AngularJS code-block.

Gibt es eine ähnliche Frage SO, aber es hat keine Antworten. Sehen https://stackoverflow.com/questions/23849665/web-api-accept-and-post-byte-array

Hier einige hintergrund-Informationen, um den Kontext, bevor ich erkläre mein problem.

  1. Ich bin versucht, erstellen Sie eine Allgemeine client - /server-Schnittstelle zum hoch-und herunterladen byte[]'s, die als Teil eines proprietären server-Datenbank.
  2. Ich bin mit TypeScript, AngularJS, JavaScript, Bootstrap, CSS auf der client erstellt eine einzelne Seite app (SPA).
  3. Ich bin mit ASP.NET Web-API/C# auf dem server.

SPA entwickelt, das ersetzen eines bereits bestehenden Produktes, das entwickelt wurde, in Silverlight, so dass es fixiert ist, um vorhandene system-Anforderungen. Der SPA muss auch das Ziel einer breiten Palette von Geräten (Handy, desktop) und die wichtigsten OSs.

Mit Hilfe von mehreren online-Ressourcen (siehe unten), ich habe die meisten von meinem code arbeiten. Ich bin über eine asynchrone multimedia-Formatierer für byte[]'s aus dem Byte-Rot link unten.

http://byterot.blogspot.com/2012/04/aspnet-web-api-series-part-5.html

Rückkehr Binärdatei vom controller in ASP.NET Web-API

  1. Ich bin mit einem jpeg konvertiert Uint8Array als meine test-Fall auf dem client.
  2. Das eigentliche system byte-arrays enthalten gemischte Inhalte komprimiert in vordefinierte Datenpakete. Allerdings brauche ich, um der Lage sein, jede gültige byte-array, so dass ein Bild einen gültigen Testfall.
  3. Die Daten an den server übertragen, korrekt mit dem client-und server-code gezeigt UND die Byte-Rot-Formatter (NICHT dargestellt, aber auf der website verfügbar).
  4. Ich habe überprüft, dass die jpeg-Datei wird richtig empfangen auf dem server als byte[] zusammen mit der string-parameter-Metadaten.
  5. Ich habe verwendet, Fiddler, um zu überprüfen, dass die richtige Antwort zurück an den client gesendet.
    • Die Größe ist richtig
    • Das Bild ist sichtbar im Fiddler.
  6. Mein problem ist, dass die Antwort des Servers in Eckigen client-code, der unten gezeigt wird, ist nicht korrekt.
    • Durch falsche, ich meine die falsche Größe (~10K versus ~27.5 K) und es ist nicht als gültigen Wert für die UintArray Konstruktor. Visual Studio zeigt, JFIF, wenn ich den cursor über die zurückgegebenen "Reaktion" gezeigt, in dem der client-code unter, aber es gibt keine andere sichtbare Anzeige der Inhalte.

/********************** Server-Code ************************/
Hinzugefügt fehlende Element, um den code nach [FromBody]byte[]

public class ItemUploadController : ApiController{ 
[AcceptVerbs("Post")]
    public HttpResponseMessage Upload(string var1, string var2, [FromBody]byte[] item){
        HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
        var stream = new MemoryStream(item);
        result.Content = new StreamContent(stream);
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        return result;
    }
}

/***************** Beispiel-Client-Code ********************/

Die einzige Sache, die ich ausgelassen habe aus dem code die eigentliche variable Parameter.

$http({
url: 'api/ItemUpload/Upload',
    method: 'POST',
    headers: { 'Content-Type': 'application/octet-stream' },//Added per Byte Rot blog...
    params: {
        //Other params here, including string metadata about uploads
        var1: var1,
        var2: var2
    },
data: new Uint8Array(item),
//arrybuffer must be lowecase. Once changed, it fixed my problem.
responseType: 'arraybuffer',//Added per http://www.html5rocks.com/en/tutorials/file/xhr2/
transformRequest: [],
})
.success((response, status) => {
    if (status === 200) {
        //The response variable length is about 10K, whereas the correct Fiddler size is ~27.5K.
        //The error that I receive here is that the constructor argument in invalid.
        //My guess is that I am doing something incorrectly with the AngularJS code, but I
        //have implemented everything that I have read about. Any thoughts???
        var unsigned8Int = new Uint8Array(response);
        //For the test case, I want to convert the byte array back to a base64 encoded string
        //before verifying with the original source that was used to generate the byte[] upload.
        var b64Encoded = btoa(String.fromCharCode.apply(null, unsigned8Int));
        callback(b64Encoded);
    }
})
.error((data, status) => {
    console.log('[ERROR] Status Code:' + status);
});

/****************************************************************/

Jede Hilfe oder Anregungen würde sehr geschätzt werden.

Dank...

Bearbeitet, um mehr diagnostische Daten

Zuerst habe ich die Winkel.isArray-Funktion, um festzustellen, dass die Antwort Wert ist und NICHT ein array, was ich denke, es sollte sein.

Zweiten, ich verwendete den folgenden code auf befragen die Antwort, das scheint ein unsichtbarer string. Die führenden Zeichen nicht zu entsprechen scheint jede gültige Sequenz, in der Bild-byte-array-code.

var buffer = new ArrayBuffer(response.length);
var data = new Uint8Array(buffer);
var len = data.length, i;
for (i = 0; i < len; i++) {
    data[i] = response[i].charCodeAt(0);
}

Experiment Ergebnisse

Lief ich ein experiment durch erstellen byte-array mit Werten von 0 - 255 auf dem server, die ich heruntergeladen habe. Die AngularJS client-empfangen der ersten 128 bytes korrekt (d.h., 0,1,...,126,127), aber die restlichen Werte waren 65535 in Internet Explorer 11, und 65533 in Chrome und Firefox. Fiddler zeigt, dass 256 Werte wurden über das Netzwerk gesendet, aber es sind nur noch 217 Zeichen, die in der AngularJS client-code. Wenn ich nur 0-127 die server-Werte, alles scheint zu funktionieren. Ich habe keine Ahnung, was das verursachen kann, aber die client-Antwort scheint mehr im Einklang mit signed Byte, das denke ich nicht möglich ist.

Fiddler Hex-Daten aus dem server zeigt 256 bytes mit den Werten von 00,01,...,EF,FF, das ist richtig. Wie ich bereits erwähnt habe, kann ich wieder ein Bild und zeigen Sie Sie richtig in Fiddler, damit die Web-API-server-interface funktioniert sowohl für POST und GET.

Ich versuche Vanille XMLHttpRequest ich sehen kann, dass die Arbeit außerhalb des AngularJS-Umgebung.

XMLHttpRequest Test-Update

War ich in der Lage zu bestätigen, dass Vanille XMLHttpRequest funktioniert mit dem server für die BEKOMMEN, und ist in der Lage, zurückzukehren, die richtige byte-codes und dem test-Bild.

Die gute Nachricht ist, dass ich hacken kann um AngularJS, um mein system zu arbeiten, aber die schlechte Nachricht ist, dass ich nicht wie dies zu tun. Ich würde lieber mit Winkel für alle meine client-Seite server-Kommunikation.

Ich werde zu öffnen, eine einzelne Frage auf Stack Overflow, die sich nur mit der GET byte[] Fragen, ich bin mit AngularJS. Wenn ich eine Auflösung, werde ich auf dieses Problem mit der Lösung für historische Zwecke, um anderen zu helfen.

Update

Eric Eslinger auf Google Groups schickte mir ein kleines code-segment hervorheben, dass responseType sollte "arraybuffer", alles in Kleinbuchstaben. Ich aktualisierte den code-block oben zeigen die groß-Wert und es wurde ein Hinweis Hinzugefügt.

Dank...

können Sie vorschlagen, die auf ähnlichen Problem bin ich unter [Frage][1] [1]: stackoverflow.com/questions/31612259/...

InformationsquelleAutor Highdown | 2014-09-23

Schreibe einen Kommentar