Czy mogę utworzyć kontroler, który po prostu zwraca zasób obrazu?
Chciałbym przekierować tę logikę przez kontroler, ilekroć wymagany jest adres URL taki jak poniżej:
www.mywebsite.com/resource/image/topbanner
Kontroler wyszuka topbanner.png
i wyśle ten obraz bezpośrednio z powrotem do klienta.
Widziałem przykłady tego, w których musisz utworzyć widok - nie chcę używać widoku. Chcę to wszystko zrobić tylko z kontrolerem.
czy to możliwe?
asp.net
asp.net-mvc
image
controller
Jonathan
źródło
źródło
ApiController class
Odpowiedzi:
Użyj metody pliku kontrolerów podstawowych.
Uwaga: wydaje się to dość wydajne. Zrobiłem test, w którym poprosiłem o obraz za pośrednictwem kontrolera (
http://localhost/MyController/Image/MyImage
) i bezpośredniego adresu URL (http://localhost/Images/MyImage.jpg
), a wyniki były następujące:Uwaga: jest to średni czas żądania. Średnia została obliczona na podstawie tysięcy żądań na komputerze lokalnym, więc sumy nie powinny obejmować opóźnień sieci ani problemów z przepustowością.
źródło
App_Data
które powinny być podpisane przez niektórych użytkowników aplikacji, ale nie przez innych. Użycie akcji kontrolera do ich obsługi pozwala ograniczyć dostęp./../../../danger/someFileTheyTHoughtWasInaccessible
Używając wydanej wersji MVC, oto co robię:
Oczywiście mam tutaj pewne specyficzne dla aplikacji rzeczy dotyczące budowy ścieżki, ale zwracanie FileStreamResult jest przyjemne i proste.
Przeprowadziłem pewne testy wydajności w odniesieniu do tej akcji przeciwko codziennemu wywołaniu obrazu (z pominięciem kontrolera), a różnica między średnimi wynosiła tylko około 3 milisekund (średnia kontrolera wynosiła 68 ms, a kontroler inna niż 65 ms).
Wypróbowałem kilka innych metod wymienionych w odpowiedziach tutaj, a wydajność była znacznie bardziej dramatyczna ... kilka odpowiedzi na rozwiązania było aż 6 razy większa niż kontroler inny (inne kontrolery średnio 340 ms, a nie kontroler 65 ms).
źródło
Path.Combine
zamiast concat dla bezpieczniejszego i bardziej czytelnego kodu.Aby nieco rozwinąć odpowiedź Dyland:
Trzy klasy implementują klasę FileResult :
Wszystkie są dość zrozumiałe:
FilePathResult
- jest to najłatwiejszy sposób i pozwala uniknąć konieczności korzystania ze strumieni.FileContentResult
.FileStreamResult
w podobny sposób jak poniżej, ale zaMemoryStream
pomocąGetBuffer()
.Streams
użytkuFileStreamResult
. To się nazywa FileStreamResult, ale zajmujeStream
tak, więc zgaduję, że działa zMemoryStream
.Poniżej znajduje się przykład zastosowania techniki rozmieszczania treści (nie testowane):
źródło
Może to być pomocne, jeśli chcesz zmodyfikować obraz przed jego zwróceniem:
źródło
Możesz utworzyć własne rozszerzenie i zrobić to w ten sposób.
źródło
Możesz napisać bezpośrednio do odpowiedzi, ale wtedy nie można jej przetestować. Preferowane jest zwrócenie ActionResult, który odroczył wykonanie. Oto mój StreamResult wielokrotnego użytku:
źródło
Dlaczego nie pójść prosto i użyć
~
operatora tyldy ?źródło
AKTUALIZACJA: Są lepsze opcje niż moja pierwotna odpowiedź. Działa to całkiem dobrze poza MVC, ale lepiej trzymać się wbudowanych metod zwracania treści obrazu. Zobacz głosowane odpowiedzi.
Z pewnością możesz. Wypróbuj następujące kroki:
Oto przykładowy kod:
Mam nadzieję, że to pomaga!
źródło
Rozwiązanie 1: Aby renderować obraz w widoku z adresu URL obrazu
Możesz stworzyć własną metodę rozszerzenia:
Następnie użyj go w następujący sposób:
Rozwiązanie 2: Aby renderować obraz z bazy danych
Utwórz metodę kontrolera, która zwraca dane obrazu, jak poniżej
I użyj go w widoku takim jak:
Aby użyć obrazu renderowanego z tej akcji w dowolnym HTML, użyj
źródło
To zadziałało dla mnie. Ponieważ przechowuję obrazy w bazie danych SQL Server.
W powyższym fragmencie
_db.ImageFiles.Find(uuid)
jest wyszukiwanie rekordu pliku obrazu w db (kontekst EF). Zwraca obiekt FileImage, który jest po prostu niestandardową klasą, którą stworzyłem dla modelu, a następnie używa go jako FileContentResult.źródło
możesz użyć Plik do zwrócenia pliku, takiego jak Widok, Treść itp
źródło
Spójrz na ContentResult. Zwraca ciąg, ale można go użyć do stworzenia własnej klasy podobnej do BinaryResult.
źródło
SomeHelper.EmptyImageResult()
powinien powrócićFileResult
z istniejącym obrazem (na przykład przezroczysty 1x1).Jest to najprostszy sposób, jeśli pliki są przechowywane na dysku lokalnym. Jeśli pliki są
byte[]
lubstream
- to użyjFileContentResult
lub,FileStreamResult
jak sugerował Dylan.źródło
Widzę dwie opcje:
1) Zaimplementuj własny IViewEngine i ustaw właściwość ViewEngine kontrolera, którego używasz, na ImageViewEngine w żądanej metodzie „image”.
2) Użyj widoku :-). Wystarczy zmienić typ zawartości itp.
źródło
Możesz użyć HttpContext.Response i bezpośrednio napisać do niego treść (WriteFile () może działać dla Ciebie), a następnie zwrócić ContentResult z akcji zamiast ActionResult.
Oświadczenie: Nie próbowałem tego, opiera się na sprawdzeniu dostępnych interfejsów API. :-)
źródło
Poniższy kod wykorzystuje
System.Drawing.Bitmap
do załadowania obrazu.źródło
Spotykałem również podobny wymóg,
Tak więc w moim przypadku przesyłam zapytanie do kontrolera ze ścieżką do folderu obrazów, która w zamian odsyła obiekt ImageResult.
Poniższy fragment kodu ilustruje pracę:
I w sterowniku ze ścieżki obrazu tworzę obraz i zwracam go z powrotem dzwoniącemu
źródło
Przeczytaj obraz, przekonwertuj go
byte[]
, a następnie zwróćFile()
z typem zawartości.Oto zastosowania:
źródło