2016-04-21 10 views
6

Ich mache eine Web API und ich muss mehrere Bilder an den Client zurückgeben. Ich verwende derzeit eine Base64-Zeichenfolge für jedes Bild, aber dies führt dazu, dass jede Anfrage viel zu lange dauert. Gibt es eine bessere, effizientere Möglichkeit, Bilder zurückzugeben?Zurückgeben von Bildern aus WebApi

Dies ist der Code ich verwende:

Controller:

public LearningUnits GetLearningUnits([FromODataUri]Guid key) 
    { 
     var record = db.LearningUnits.SingleOrDefault(inst => inst.LearningUnitId == key); 

     record.ImageURLPath = ImageHandler.ImageToByteArrayFromFilePath(record.ImageURLPath); 

     return record; 
    } 

ImageToByteArray Methode:

public static string ImageToByteArrayFromFilePath(string imagefilePath) 
    { 
     byte[] imageArray = File.ReadAllBytes(imagefilePath); 

     string baseImage = Convert.ToBase64String(imageArray); 

     return baseImage; 
    } 
+0

Wie viele solcher Bilder gibt es insgesamt? –

+5

Warum können Sie keine URL in Ihrem Modell zurückgeben, und der Client wird dann weitere Anforderungen stellen, um Image-Binärdateien zu erhalten? – tenbits

+0

Hängt von der Anzahl der Datensätze in der Datenbank ab. Jeder Datensatz hat ein Bild. So könnte es 1 bis 1000 sein. –

Antwort

0

Die Lösung besteht darin, Medienformatierer zu verwenden, so dass Sie dann, wenn die Web-API mit einem bestimmten Typ abgefragt wird, den eigentlichen Binärdatenstrom des bestimmten Typs erhalten.

http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters

Dies ist die Standard RESTful Muster; Sie haben dieselbe URL, aber wenn Sie einen JSON-Datensatz für die Daten wünschen, akzeptieren Sie: application/json, aber Sie ändern Ihren MIME-Anforderungstyp in image/png oder etwas ähnliches, wenn Sie diesen Medientyp möchten.

Mehr finden Sie hier: How to provide custom mediatype formats for OData Api

OData auch implizit hier unterstützt: https://msdn.microsoft.com/en-us/library/system.web.http.odata.formatter.odatamediatypeformatter(v=vs.118).aspx

+1

Es ist keine gute Idee, verschiedene Daten für einen einzelnen Endpunkt zurückzugeben. MediaFormatters eignen sich nur für unterschiedliche Formatierung der ** gleichen ** Daten. Andernfalls wird das Prinzip der einheitlichen Verantwortlichkeit aufgehoben und ist kein übliches REST-konformes Muster. Sicher können Sie das Bild anstelle von json zurückgeben, aber nur für den Fall, dass das Bild die Daten vollständig darstellt. – tenbits

+0

Ich stimme respektvoll zu; Wenn das Bild für die fragliche Entität repräsentativ ist, könnten Sie argumentieren, dass dies der Inhaltstyp dieser bestimmten Entität ist. Wenn es nur eine Bildvisualisierung für eine Datenentität gibt, dann ist diese Bildvisualisierung auch dann geeignet, wenn das Bild nicht die vollständige Darstellung der gesamten Entität ist (was gleichwohl Telemetrie usw. von etwas wie OData umfassen kann). Wenn wir Ihre Logik zu seiner vollständigen Schlussfolgerung gebracht haben, dann sollten wir das Objekt nicht einmal als eine Anwendung/json oder application/xml darstellen, weil es sich grundlegend von der nativen Form der Daten unterscheidet. –

+0

Die Benennung 'MediaType' **' Formatter' ** besagt, dass nur der Formatierer für die Entität unterschiedlich ist. Sicher, durch Serialisierung der Daten zu einem bestimmten Typ könnten mehr oder weniger Informationen vorliegen. Betrachte den Endpunkt '[get]/api/v1/blog/123', wenn du ihn mit' accept: image/png' anforderst, reicht es nicht aus, nur ein Hauptbild des Blogposts zurückzugeben, aber es wäre in Ordnung erzeuge das Bild mit dem Titel darüber. Wenn jemand nur einen Eigenschaftswert wie 'ImageURLPath' zurückgeben möchte, sollte der explizite Endpunkt definiert werden:' [get]/api/v1/blog/123/image'. – tenbits

1

Wenn der Endpunkt json zurückgibt, dann gibt es keine andere Möglichkeit, über base64 , wie Binärdateien in die Antwort eingebettet werden. Aber es ist definitiv eine schlechte Idee wegen der Leistungsprobleme. Mag für einige Icons ok sein, aber für größere Bilder ist es nicht geeignet.

Die beste Lösung hier ist, die URL zum Bild zurück zu geben. Und der Client wird weitere Anforderungen stellen, um Rohbytes für das Bild zu erhalten.

Auch die Image-URL kann nicht nur der Pfad zur statischen Datei sein, sondern auch ein Pfad zu einem Webapi-Endpunkt, der beispielsweise die Image-Bytes von der Ressourcen-ID abruft und den Client raw sendet Binär zurück und keine JSON-Zeichenfolge.

+0

Ich habe beschlossen, diese Route zu gehen. Ich habe keine besseren Optionen gefunden und dies wäre die effizienteste –

Verwandte Themen