Téléchargement / Téléchargement de tableaux d'octets avec AngularJS et API Web ASP.NET

J'ai passé plusieurs jours de recherche, et de travailler sur une solution pour le téléchargement/téléchargement byte []. Je suis proche, mais ont un autre problème qui semble être dans mon AngularJS bloc de code.

Il y a une question similaire, mais il n'a pas de réponses. Voir https://stackoverflow.com/questions/23849665/web-api-accept-and-post-byte-array

Voici quelques informations de base pour définir le contexte avant que je déclare mon problème.

  1. Je cherche à créer un general purpose interface client/serveur pour télécharger des byte[]’s, qui sont utilisés dans le cadre d'un propriétaire base de données du serveur.
  2. Je suis à l'aide de caractères d'imprimerie, AngularJS, JavaScript, CSS et Bootstrap sur le client pour créer une page de l'app (SPA).
  3. Je suis en utilisant ASP.NET Web API/C# sur le serveur.

Le SPA est en cours d'élaboration pour remplacer un produit existant qui a été développé en Silverlight, donc il est contraint à l'existant, les exigences du système. Le SPA doit également cibler une large gamme d'appareils (mobile et desktop) et les principaux systèmes d'exploitation.

Avec l'aide de plusieurs ressources en ligne (ci-dessous), j'ai obtenu la plupart de mon code de travail. Je suis en utilisant un asynchrones multimédia formateur pour l'byte[]’partir de l'Octet de la Pourriture lien ci-dessous.

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

De retour de fichier binaire de contrôleur ASP.NET Web API

  1. Je suis à l'aide d'un jpeg converti en Uint8Array que mon cas de test sur le client.
  2. Le système des tableaux d'octets contiennent contenu mixte compacté en prédéfinies de paquets de données. Cependant, j'ai besoin d'être en mesure de gérer toutes les valides tableau d'octets, de sorte qu'une image est valide d'un cas de test.
  3. La transmission des données vers le serveur correctement en utilisant le client et le serveur de code ci-dessous ET de l'Octet de la Pourriture Formateur (PAS illustré mais disponible sur leur site).
  4. J'ai vérifié que le jpeg est reçu correctement sur le serveur comme un byte[] avec le paramètre de la chaîne de métadonnées.
  5. J'ai utilisé le Violoneux, afin de vérifier que la bonne réponse est envoyée au client.
    • La taille est correcte
    • L'image est visible dans un violon.
  6. Mon problème est que la réponse du serveur dans l'angle de client code ci-dessous n'est pas correct.
    • Par incorrecteje veux dire la mauvaise taille (~10K contre ~27.5 K) et il est pas reconnu comme une valeur valide pour le UintArray constructeur. Visual Studio affiche JFIF lorsque je place le curseur sur le retour de “réponse”, indiqué dans le code du client ci-dessous, mais il n'y a pas d'autre indicateur visible du contenu.

/********************** Code Serveur ************************/
Ajouté l'article manquant de code après [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;
    }
}

/***************** Exemple De Code Client ********************/

La seule chose que j'ai omis de le code sont les réelles de la variable de paramètres.

$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);
});

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

De l'aide ou des suggestions seraient grandement appréciés.

Merci...

Modifié pour inclure plus de données de diagnostic

Tout d'abord, j'ai utilisé le angulaires.isArray fonction pour déterminer que la valeur de la réponse n'est PAS un tableau, je pense qu'il devrait être.

Deuxième, j'ai utilisé le code suivant pour interroger la réponse, qui semble être une invisible chaîne. Les personnages principaux ne semblent pas correspondre à toute séquence valide à l'image du tableau d'octets de 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);
}

Résultats De L'Expérience

J'ai couru une expérience par la création de tableau d'octets valeurs de 0 à 255 sur le serveur, que j'ai téléchargé. Le AngularJS client a reçu les 128 premiers octets correctement (c'est à dire, 0,1,...,126,127), mais les valeurs restantes ont été 65535 dans Internet Explorer 11, et 65533 dans Chrome et Firefox. Fiddler montre que 256 valeurs ont été envoyées sur le réseau, mais il y a seulement 217 caractères reçus dans le AngularJS code client. Si je n'utilise 0-127 que le serveur valeurs, tout semble fonctionner. Je n'ai aucune idée de ce que peuvent être en cause, mais la réponse du client semble plus en ligne avec l'signé octets, je ne pense pas que c'est possible.

Fiddler Hex de données à partir du serveur montre 256 octets avec des valeurs allant de 00,01,...,EF,FF, ce qui est correct. Comme je l'ai mentionné plus tôt, je peux retourner une image et l'afficher correctement dans un violon, de sorte que le Web API d'interface serveur fonctionne pour les deux POST et GET.

Je suis en train de vanille XMLHttpRequest pour voir je peux obtenir que le travail à l'extérieur de la AngularJS environnement.

XMLHttpRequest Tests De Mise À Jour

J'ai été en mesure de confirmer que la vanille XMLHttpRequest fonctionne avec le serveur pour l'OBTENIR et est en mesure de retourner le bon d'octets de codes et de l'image de test.

La bonne nouvelle, c'est que je peux pirater autour AngularJS pour obtenir mon système de travail, mais la mauvaise nouvelle est que je n'aime pas faire cela. Je préfère rester avec Angulaire pour tous mes côté client, le serveur de communication.

Je vais ouvrir un sujet séparé sur un Débordement de Pile qui ne traite que de l'OBTENIR byte[] les questions que je me suis avoir avec AngularJS. Si je peux obtenir une résolution, je mettrai à jour ce problème avec la solution à des fins historiques pour aider les autres.

Mise à jour

Eric Eslinger sur des Groupes de Google m'a envoyé un petit segment de code en soulignant que responseType doit être "arraybuffer", en bas de casse. J'ai mis à jour le bloc de code ci-dessus pour afficher la minuscule de la valeur et de l'ajout d'une note.

Merci...

source d'informationauteur Highdown