web-dev-qa-db-fra.com

Web API Controller convertit MemoryStream en StreamContent

J'ai une grande collection d'images stockées sur un serveur sécurisé dont certaines doivent être affichées sur un portail orienté vers le monde. Le serveur du portail se trouve à l'intérieur d'un DMZ qui autorise les requêtes mais empêche les requêtes directes de passer au domaine sécurisé. Les images sont cataloguées à l'aide de SOLR et peuvent être téléchargées via un serveur interne (apache?) À partir de http://intenalname/folderA/folderAB/file.jpg

Dans mon PhotoController je peux créer une instance de WebClient, lui donner l'url et obtenir un MemoryStream. Si j'essaie d'utiliser ce flux de mémoire pour remplir le contenu de la réponse, j'obtiens une réponse vide (par violoneux). Si j'utilise le flux de mémoire pour écrire dans un fichier local, puis lire le fichier (en utilisant un FileStream et FileInfo) cela fonctionne "comme prévu".

Je devrais pouvoir passer d'un MemoryStream à StreamContent sans passer par le système de fichiers (ne devrais-je pas) ?? mais comment? Le constructeur par défaut de StreamContent(stream) accepte l'instance de flux de mémoire sans erreur de compilation ... mais cela "ne fonctionne pas".

HttpResponseMessage response = Request.CreateResponse();

using (WebClient webClient = new WebClient())
{
    string url = string.Format(PHOTO_GET, filePath);
    using (MemoryStream memoryStream = new MemoryStream(webClient.DownloadData(url)))
    {
        // If these lines are unremarked the stream moves 'through' the file system and works (?!)
        //memoryStream.Position = 0;
        //string tempName = @"c:\test\" + Guid.NewGuid().ToString() + ".jpg";
        //var fs = new FileStream(tempName, FileMode.OpenOrCreate);
        //stream.CopyTo(fs);
        //fs.Close();
        //FileInfo fi = new FileInfo(tempName);

        response.Headers.AcceptRanges.Add("bytes");
        response.StatusCode = HttpStatusCode.OK;
        //response.Content =  new StreamContent(fi.ReadStream());
        response.Content = new StreamContent(memoryStream);
        response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("render");
        response.Content.Headers.ContentDisposition.FileName = fileName;
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpg");//("application/octet-stream");
        response.Content.Headers.ContentLength = memoryStream.Length;

    }

}
return response;

Lors des tests via Fiddler, j'obtiens:

[Fiddler] ReadResponse () a échoué: le serveur n'a pas renvoyé de réponse complète pour cette demande. Le serveur a renvoyé 0 octets.

(lorsque vous parcourez FileStream Fiddler me montre l'image.)

16
Cos Callis

Dans votre code, le flux de mémoire est supprimé avant de pouvoir transmettre son contenu à la réponse. La réponse renvoyée utilisera un flux de mémoire disposé, il n'y a donc rien à retourner, d'où les 0 octets dans le violon.

HttpResponseMessage response = Request.CreateResponse();

using (WebClient webClient = new WebClient())
{
    string url = string.Format(PHOTO_GET, filePath);
    var memoryStream = new MemoryStream(webClient.DownloadData(url));

    response.Headers.AcceptRanges.Add("bytes");
    response.StatusCode = HttpStatusCode.OK;
    response.Content = new StreamContent(memoryStream);
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("render");
    response.Content.Headers.ContentDisposition.FileName = fileName;
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpg");
    response.Content.Headers.ContentLength = memoryStream.Length;            
}
return response;
26
Nkosi