2013-01-23 8 views
18

Non riesco a stampare un'immagine da byte [] dal mio database in NancyFX a un flusso di output Web. Non ho codice di esempio abbastanza vicino da poterlo mostrare anche a questo punto. Mi stavo chiedendo se qualcuno ha affrontato questo problema e potrebbe pubblicare uno snippet? Fondamentalmente voglio solo restituire l'immagine/jpeg da una matrice di byte memorizzata nel mio database e metterla sul web piuttosto che su un file fisico.Come creare un gestore di immagini in NancyFx

risposta

27

giusto per costruire su @ risposta di TheCodeJunkie, si può costruire una "risposta di array di byte" molto facilmente in questo modo:

public class ByteArrayResponse : Response 
{ 
    /// <summary> 
    /// Byte array response 
    /// </summary> 
    /// <param name="body">Byte array to be the body of the response</param> 
    /// <param name="contentType">Content type to use</param> 
    public ByteArrayResponse(byte[] body, string contentType = null) 
    { 
     this.ContentType = contentType ?? "application/octet-stream"; 

     this.Contents = stream => 
      { 
       using (var writer = new BinaryWriter(stream)) 
       { 
        writer.Write(body); 
       } 
      }; 
    } 
} 

Poi, se si desidera utilizzare la sintassi Response.AsX è un metodo semplice estensione sulla parte superiore:

public static class Extensions 
{ 
    public static Response FromByteArray(this IResponseFormatter formatter, byte[] body, string contentType = null) 
    { 
     return new ByteArrayResponse(body, contentType); 
    } 
} 

Poi, nel tuo percorso si può semplicemente utilizzare:

Response.FromByteArray(myImageByteArray, "image/jpeg"); 

È potrebbe anche aggiungere un processore per utilizzare un array di byte con negoziazione del contenuto, ne ho aggiunto un rapido esempio a this gist

+0

Grazie mille per l'espansione della soluzione, è esattamente ciò di cui avevo bisogno. – sethxian

+0

C'è un modo per fare in modo che il browser memorizzi nella cache la risposta dell'array di byte della richiesta? In modo che il gestore non lavori di nuovo per lo stesso URL? – Azadrum

+1

Questo è terribile, quella cache è i byte in memoria. Non puoi eseguire lo streaming direttamente (utilizzando una memoria minima)? – Todd

8

Da Nancy è possibile restituire un nuovo oggetto Response. E 'Content proprietà è di tipo Action<Stream> così si può solo creare un delegato che scrive l'array di byte a quel flusso

var r = new Response(); 
r.Content = s => { 
    //write to s 
}; 

Non dimenticare di impostare la proprietà ContentType (si potrebbe usare MimeTypes.GetMimeType e passarlo il nome, tra cui estensione) C'è anche un StreamResponse, che eredita da Response e fornisce un costruttore diverso (per un po 'la sintassi più bello è possibile utilizzare return Response.AsStream(..) nel percorso .. solo caramelle sintassi)

+0

Grazie per l'aiuto, mi piacciono le soluzioni alternative che hai presentato. – sethxian

+0

Sembra che il nome della proprietà sia cambiato in 'Contents'. – TrueWill

11

In il tuo controller, restituisci Response.FromStream con un flusso di byte dell'immagine. Si chiamava AsStream nelle vecchie versioni di nancy.

Get["/Image/{ImageID}"] = parameters => 
{ 
    string ContentType = "image/jpg"; 
    Stream stream = // get a stream from the image. 

    return Response.FromStream(stream, ContentType); 
}; 
+0

Come si suppone di chiudere lo stream sorgente con questa API? Terribile. – Todd

+2

Il flusso di origine viene eliminato automaticamente in seguito -https: //github.com/NancyFx/Nancy/issues/786 – Todd

+1

È necessario assicurarsi che la posizione dello stream sia impostata all'inizio dello stream: 'stream.Seek (0, SeekOrigin.Begin) ', poiché' FromStream' non lo farà per te. –

Problemi correlati