Kann ich einen Controller erstellen, der einfach ein Image-Asset zurückgibt?
Ich möchte diese Logik durch einen Controller leiten, wenn eine URL wie die folgende angefordert wird:
www.mywebsite.com/resource/image/topbanner
Der Controller wird nachschlagen topbanner.png
und sendet das Bild direkt an den Client zurück.
Ich habe Beispiele dafür gesehen, in denen Sie eine Ansicht erstellen müssen - ich möchte keine Ansicht verwenden. Ich möchte alles nur mit dem Controller machen.
Ist das möglich?
asp.net
asp.net-mvc
image
controller
Jonathan
quelle
quelle
ApiController class
Antworten:
Verwenden Sie die Dateimethode der Basiscontroller.
Als Hinweis scheint dies ziemlich effizient zu sein. Ich habe einen Test durchgeführt, bei dem ich das Bild über den Controller (
http://localhost/MyController/Image/MyImage
) und die direkte URL (http://localhost/Images/MyImage.jpg
) angefordert habe. Die Ergebnisse waren:Hinweis: Dies ist die durchschnittliche Zeit einer Anfrage. Der Durchschnitt wurde berechnet, indem Tausende von Anforderungen auf dem lokalen Computer gestellt wurden. Daher sollten die Gesamtsummen keine Probleme mit der Netzwerklatenz oder der Bandbreite enthalten.
quelle
App_Data
, die von einigen Benutzern Ihrer Anwendung signiert werden sollten, von anderen jedoch nicht. Durch die Verwendung einer Controller-Aktion können Sie den Zugriff einschränken./../../../danger/someFileTheyTHoughtWasInaccessible
Mit der Release-Version von MVC mache ich Folgendes:
Ich habe hier natürlich einige anwendungsspezifische Dinge bezüglich der Pfadkonstruktion, aber die Rückgabe des FileStreamResult ist nett und einfach.
Ich habe einige Leistungstests in Bezug auf diese Aktion gegen Ihren täglichen Aufruf des Bildes (unter Umgehung des Controllers) durchgeführt, und die Differenz zwischen den Durchschnittswerten betrug nur etwa 3 Millisekunden (der durchschnittliche Controller betrug 68 ms, der Nicht-Controller betrug 65 ms).
Ich hatte einige der anderen Methoden ausprobiert, die in den Antworten hier erwähnt wurden, und der Leistungseinbruch war viel dramatischer ... Einige der Lösungsantworten waren bis zum 6-fachen des Nicht-Controllers (andere Controller durchschnittlich 340 ms, Nicht-Controller 65 ms).
quelle
Path.Combine
anstelle von concat sichereren und besser lesbaren Code verwenden.Um Dylands Antwort etwas näher zu erläutern:
Drei Klassen implementieren die FileResult- Klasse:
Sie sind alle ziemlich selbsterklärend:
FilePathResult
dies. Dies ist der einfachste Weg und vermeidet die Verwendung von Streams.FileContentResult
.FileStreamResult
auf ähnliche Weise wie unten, jedoch mit aMemoryStream
und usingGetBuffer()
.Streams
VerwendungFileStreamResult
. Es heißt FileStreamResult, aber es dauert ein,Stream
also würde ich vermuten, dass es mit einem funktioniertMemoryStream
.Nachfolgend finden Sie ein Beispiel für die Verwendung der Technik zur Inhaltsdisposition (nicht getestet):
quelle
Dies kann hilfreich sein, wenn Sie das Bild vor der Rückgabe ändern möchten:
quelle
Sie können Ihre eigene Erweiterung erstellen und auf diese Weise vorgehen.
quelle
Sie können direkt in die Antwort schreiben, diese ist jedoch nicht testbar. Es wird bevorzugt, ein ActionResult zurückzugeben, dessen Ausführung verzögert wurde. Hier ist mein wiederverwendbares StreamResult:
quelle
Warum nicht einfach den Tilde-
~
Operator verwenden?quelle
UPDATE: Es gibt bessere Optionen als meine ursprüngliche Antwort. Dies funktioniert außerhalb von MVC recht gut, aber es ist besser, sich an die integrierten Methoden zur Rückgabe von Bildinhalten zu halten. Siehe hochgestimmte Antworten.
Das kannst du sicher. Probieren Sie diese Schritte aus:
Hier ist ein Beispielcode:
Ich hoffe, das hilft!
quelle
Lösung 1: Rendern eines Bildes in einer Ansicht von einer Bild-URL
Sie können Ihre eigene Erweiterungsmethode erstellen:
Dann benutze es wie folgt:
Lösung 2: Rendern von Bildern aus der Datenbank
Erstellen Sie eine Controller-Methode, die Bilddaten wie unten zurückgibt
Und verwenden Sie es in einer Ansicht wie:
Verwenden Sie, um ein aus diesem Aktionsergebnis gerendertes Bild in einem beliebigen HTML-Code zu verwenden
quelle
Das hat bei mir funktioniert. Da ich Bilder in einer SQL Server-Datenbank speichere.
Im obigen Snippet
_db.ImageFiles.Find(uuid)
wird nach dem Bilddateidatensatz in der Datenbank (EF-Kontext) gesucht. Es gibt ein FileImage-Objekt zurück, das nur eine benutzerdefinierte Klasse ist, die ich für das Modell erstellt habe, und verwendet es dann als FileContentResult.quelle
Sie können Datei verwenden, um eine Datei wie Ansicht, Inhalt usw. zurückzugeben
quelle
Schauen Sie sich ContentResult an. Dies gibt eine Zeichenfolge zurück, kann jedoch verwendet werden, um eine eigene BinaryResult-ähnliche Klasse zu erstellen.
quelle
SomeHelper.EmptyImageResult()
sollteFileResult
mit vorhandenem Bild zurückkehren (z. B. 1x1 transparent).Dies ist der einfachste Weg, wenn Sie Dateien auf dem lokalen Laufwerk gespeichert haben. Wenn Dateien
byte[]
oderstream
- sind, verwenden SieFileContentResult
oderFileStreamResult
wie von Dylan vorgeschlagen.quelle
Ich sehe zwei Möglichkeiten:
1) Implementieren Sie Ihre eigene IViewEngine und setzen Sie die ViewEngine-Eigenschaft des Controllers, den Sie verwenden, in Ihrer gewünschten "image" -Methode auf Ihre ImageViewEngine.
2) Verwenden Sie eine Ansicht :-). Ändern Sie einfach den Inhaltstyp usw.
quelle
Sie können die HttpContext.Response verwenden und den Inhalt direkt darauf schreiben (WriteFile () funktioniert möglicherweise für Sie) und dann ContentResult von Ihrer Aktion anstelle von ActionResult zurückgeben.
Haftungsausschluss: Ich habe dies nicht versucht, es basiert auf der Überprüfung der verfügbaren APIs. :-)
quelle
Der folgende Code wird
System.Drawing.Bitmap
zum Laden des Bildes verwendet.quelle
Ich bin auch auf eine ähnliche Anforderung gestoßen,
In meinem Fall stelle ich eine Anfrage an Controller mit dem Bildordnerpfad, der im Gegenzug ein ImageResult-Objekt zurücksendet.
Das folgende Codefragment veranschaulicht die Arbeit:
Und im Controller aus dem Bildpfad produziere ich das Bild und gebe es an den Anrufer zurück
quelle
Lesen Sie das Bild, konvertieren Sie es in
byte[]
und geben Sie einFile()
mit einem Inhaltstyp zurück.Hier sind die Verwendungen:
quelle