Мы разрабатываем PythonAnywhere , чтобы заполнить именно эту нишу. Мы настроили его сначала на работу с iPad. Но похоже, что Nexus 7 достаточно популярен сейчас, что может потребоваться достаточно многого для Android.
Используйте метод File базовых контроллеров.
public ActionResult Image(string id)
{
var dir = Server.MapPath("/Images");
var path = Path.Combine(dir, id + ".jpg"); //validate the path for security or use other means to generate the path.
return base.File(path, "image/jpeg");
}
В качестве примечания, это кажется довольно эффективным. Я провел тест, в котором запросил изображение через контроллер ( http: // localhost / MyController / Image / MyImage
) и через прямой URL-адрес ( http: // localhost / Images / MyImage. jpg
) и получили следующие результаты:
Примечание: это среднее время запроса. Среднее значение было рассчитано путем выполнения тысяч запросов на локальном компьютере, поэтому итоговые значения не должны включать задержки в сети или проблемы с пропускной способностью.
Вы могли использовать HttpContext. Ответ и непосредственно пишет содержание в него (WriteFile () мог бы работать на Вас), и затем возвратите ContentResult из своего действия вместо ActionResult.
Правовая оговорка: Я не попробовал это, это основано на рассмотрении доступных API.:-)
Взгляд на ContentResult. Это возвращает строку, но может использоваться для создания собственного подобного BinaryResult класса.
Я вижу две опции:
1) Реализация Ваш собственный IViewEngine и набор свойство ViewEngine Контроллера Вы используете для своего ImageViewEngine в Вашем желаемом методе "изображения".
2) Использование представление:-). Просто измените тип контента и т.д.
Можно записать непосредственно в ответ, но тогда это не является тестируемым. Это предпочтено для возврата ActionResult, который задержал выполнение. Вот мой resusable StreamResult:
public class StreamResult : ViewResult
{
public Stream Stream { get; set; }
public string ContentType { get; set; }
public string ETag { get; set; }
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.ContentType = ContentType;
if (ETag != null) context.HttpContext.Response.AddHeader("ETag", ETag);
const int size = 4096;
byte[] bytes = new byte[size];
int numBytes;
while ((numBytes = Stream.Read(bytes, 0, size)) > 0)
context.HttpContext.Response.OutputStream.Write(bytes, 0, numBytes);
}
}
ОБНОВЛЕНИЕ: существуют более оптимальные варианты, чем мой исходный ответ. Это работает за пределами MVC вполне хорошо, но лучше придерживаться встроенных методов возврата содержимого изображения. См. проголосовавшие ответы.
Вы, конечно, можете. Испытайте эти шаги:
Вот является некоторым примером кода:
string pathToFile = @"C:\Documents and Settings\some_path.jpg";
byte[] imageData = File.ReadAllBytes(pathToFile);
Response.ContentType = "image/jpg";
Response.BinaryWrite(imageData);
Hope, которая помогает!
Я также встретился с подобным требованием,
Так в моем случае, я выполняю запрос к Контроллеру с путем к папке изображения, который в ответ передает объект ImageResult обратно.
После фрагмента кода иллюстрируют работу:
var src = string.Format("/GenericGrid.mvc/DocumentPreviewImageLink?fullpath={0}&routingId={1}&siteCode={2}", fullFilePath, metaInfo.RoutingId, da.SiteCode);
if (enlarged)
result = "<a class='thumbnail' href='#thumb'>" +
"<img src='" + src + "' height='66px' border='0' />" +
"<span><img src='" + src + "' /></span>" +
"</a>";
else
result = "<span><img src='" + src + "' height='150px' border='0' /></span>";
И в Контроллере от канал передачи изображения я произвожу изображение и возвращаю его назад вызывающей стороне
try
{
var file = new FileInfo(fullpath);
if (!file.Exists)
return string.Empty;
var image = new WebImage(fullpath);
return new ImageResult(new MemoryStream(image.GetBytes()), "image/jpg");
}
catch(Exception ex)
{
return "File Error : "+ex.ToString();
}
Используя релизную версию MVC, вот что я делаю:
[AcceptVerbs(HttpVerbs.Get)]
[OutputCache(CacheProfile = "CustomerImages")]
public FileResult Show(int customerId, string imageName)
{
var path = string.Concat(ConfigData.ImagesDirectory, customerId, "\\", imageName);
return new FileStreamResult(new FileStream(path, FileMode.Open), "image/jpeg");
}
У меня, очевидно, есть кое-какие специфичные для приложения вещи в здесь относительно построения пути, но возвращение FileStreamResult приятно и просто.
Я провел некоторое тестирование производительности в отношении этого действия в отношении вашего ежедневного обращения к изображению (в обход контроллера), и разница между средними составляла только около 3 миллисекунд (среднее значение для контроллера составляло 68 мс, для неконтроллера было 65 мс).
Я попробовал некоторые из других методов, упомянутых в ответах здесь, и снижение производительности было гораздо более драматичным ... некоторые из ответов решения были в 6 раз неконтроллерными (другие контроллеры в среднем 340 мс, неконтроллерные 65 мс ).
Ниже кода использует System.Drawing.Bitmap
для загрузки изображения.
using System.Drawing;
using System.Drawing.Imaging;
public IActionResult Get()
{
string filename = "Image/test.jpg";
var bitmap = new Bitmap(filename);
var ms = new System.IO.MemoryStream();
result.Save(ms, ImageFormat.Jpeg);
ms.Position = 0;
return new FileStreamResult(ms, "image/jpeg");
}
Чтобы немного пояснить ответ Диланда:
Три класса реализуют класс FileResult :
System.Web.Mvc.FileResult
System.Web.Mvc.FileContentResult
System.Web.Mvc.FilePathResult
System.Web.Mvc.FileStreamResult
Все они достаточно понятны:
FilePathResult
- это самый простой способ, позволяющий избежать использования потоков. FileContentResult
. FileStreamResult
аналогично описанному ниже, но с MemoryStream
и с помощью GetBuffer ()
. потоков
используйте FileStreamResult
. Он называется FileStreamResult, но для него требуется Stream
, поэтому я предполагаю , что он работает с MemoryStream
. Ниже приведен пример использования метода размещения контента (не тестировался):
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult GetFile()
{
// No need to dispose the stream, MVC does it for you
string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", "myimage.png");
FileStream stream = new FileStream(path, FileMode.Open);
FileStreamResult result = new FileStreamResult(stream, "image/png");
result.FileDownloadName = "image.png";
return result;
}
if (!System.IO.File.Exists(filePath))
return SomeHelper.EmptyImageResult(); // preventing JSON GET/POST exception
else
return new FilePathResult(filePath, contentType);
SomeHelper.EmptyImageResult ()
должен вернуть FileResult
с существующим изображением (например, прозрачным 1x1).
Это самый простой способ, если у вас есть файлы, хранящиеся на локальном диске.
Если файлы представляют собой байт []
или поток
, тогда используйте FileContentResult
] или FileStreamResult
, как предложил Дилан.